Flutter Engine
 
Loading...
Searching...
No Matches
test_gl_surface.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <EGL/egl.h>
8#include <GLES2/gl2.h>
9
10#include <memory>
11#include <string>
12
13#include "flutter/fml/logging.h"
15#include "third_party/skia/include/core/SkColorSpace.h"
16#include "third_party/skia/include/core/SkColorType.h"
17#include "third_party/skia/include/core/SkSurface.h"
18#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
19#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
20#include "third_party/skia/include/gpu/ganesh/gl/GrGLAssembleInterface.h"
21#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
22#include "third_party/skia/include/gpu/ganesh/gl/GrGLDirectContext.h"
23#include "third_party/skia/include/gpu/ganesh/gl/GrGLTypes.h"
24
25namespace flutter::testing {
26
28 std::shared_ptr<TestEGLContext> context,
30 : surface_size_(size), egl_context_(std::move(context)) {
31 const EGLint attributes[] = {
32 EGL_WIDTH, size.width, //
33 EGL_HEIGHT, size.height, //
34 EGL_NONE,
35 };
36
38 ::eglCreatePbufferSurface(egl_context_->display, // display connection
39 egl_context_->config, // config
40 attributes // surface attributes
41 );
42 FML_CHECK(onscreen_surface_ != EGL_NO_SURFACE) << GetEGLError();
43}
44
46 skia_context_ = nullptr;
47
48 auto result = ::eglDestroySurface(egl_context_->display, onscreen_surface_);
49 FML_CHECK(result == EGL_TRUE) << GetEGLError();
50}
51
55
57 auto result =
58 ::eglMakeCurrent(egl_context_->display, onscreen_surface_,
59 onscreen_surface_, egl_context_->onscreen_context);
60
61 if (result == EGL_FALSE) {
62 FML_LOG(ERROR) << "Could not make the context current. " << GetEGLError();
63 }
64
65 return result == EGL_TRUE;
66}
67
69 auto result = ::eglMakeCurrent(egl_context_->display, EGL_NO_SURFACE,
70 EGL_NO_SURFACE, EGL_NO_CONTEXT);
71
72 if (result == EGL_FALSE) {
73 FML_LOG(ERROR) << "Could not clear the current context. " << GetEGLError();
74 }
75
76 return result == EGL_TRUE;
77}
78
80 auto result = ::eglSwapBuffers(egl_context_->display, onscreen_surface_);
81
82 if (result == EGL_FALSE) {
83 FML_LOG(ERROR) << "Could not swap buffers. " << GetEGLError();
84 }
85
86 return result == EGL_TRUE;
87}
88
90 uint32_t height) const {
91 return GetWindowFBOId();
92}
93
95 if (name == nullptr) {
96 return nullptr;
97 }
98 auto symbol = ::eglGetProcAddress(name);
99 if (symbol == NULL) {
100 FML_LOG(ERROR) << "Could not fetch symbol for name: " << name;
101 }
102 return reinterpret_cast<void*>(symbol);
103}
104
106 if (skia_context_) {
107 return skia_context_;
108 }
109
110 return CreateGrContext();
111}
112
114 if (!MakeCurrent()) {
115 return nullptr;
116 }
117
118 auto get_string =
119 reinterpret_cast<PFNGLGETSTRINGPROC>(GetProcAddress("glGetString"));
120
121 if (!get_string) {
122 return nullptr;
123 }
124
125 auto c_version = reinterpret_cast<const char*>(get_string(GL_VERSION));
126
127 if (c_version == NULL) {
128 return nullptr;
129 }
130
131 GrGLGetProc get_proc = [](void* context, const char name[]) -> GrGLFuncPtr {
132 return reinterpret_cast<GrGLFuncPtr>(
133 reinterpret_cast<TestGLOnscreenOnlySurface*>(context)->GetProcAddress(
134 name));
135 };
136
137 std::string version(c_version);
138 auto interface = version.find("OpenGL ES") == std::string::npos
139 ? GrGLMakeAssembledGLInterface(this, get_proc)
140 : GrGLMakeAssembledGLESInterface(this, get_proc);
141
142 if (!interface) {
143 return nullptr;
144 }
145
146 skia_context_ = GrDirectContexts::MakeGL(interface);
147 return skia_context_;
148}
149
151 FML_CHECK(::eglGetCurrentContext() != EGL_NO_CONTEXT);
152
153 GrGLFramebufferInfo framebuffer_info = {};
154 const uint32_t width = surface_size_.width;
155 const uint32_t height = surface_size_.height;
156 framebuffer_info.fFBOID = GetFramebuffer(width, height);
157#if FML_OS_MACOSX
158 framebuffer_info.fFormat = 0x8058; // GL_RGBA8
159#else
160 framebuffer_info.fFormat = 0x93A1; // GL_BGRA8;
161#endif
162
163 auto backend_render_target =
164 GrBackendRenderTargets::MakeGL(width, // width
165 height, // height
166 1, // sample count
167 8, // stencil bits
168 framebuffer_info // framebuffer info
169 );
170
171 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
172
173 auto surface = SkSurfaces::WrapBackendRenderTarget(
174 GetGrContext().get(), // context
175 backend_render_target, // backend render target
176 kBottomLeft_GrSurfaceOrigin, // surface origin
177 kN32_SkColorType, // color type
178 SkColorSpace::MakeSRGB(), // color space
179 &surface_properties, // surface properties
180 nullptr, // release proc
181 nullptr // release context
182 );
183
184 if (!surface) {
185 FML_LOG(ERROR) << "Could not wrap the surface while attempting to "
186 "snapshot the GL surface.";
187 return nullptr;
188 }
189
190 return surface;
191}
192
195
196 if (!surface) {
197 FML_LOG(ERROR) << "Aborting snapshot because of on-screen surface "
198 "acquisition failure.";
199 return nullptr;
200 }
201
202 auto device_snapshot = surface->makeImageSnapshot();
203
204 if (!device_snapshot) {
205 FML_LOG(ERROR) << "Could not create the device snapshot while attempting "
206 "to snapshot the GL surface.";
207 return nullptr;
208 }
209
210 auto host_snapshot = device_snapshot->makeRasterImage(nullptr);
211
212 if (!host_snapshot) {
213 FML_LOG(ERROR) << "Could not create the host snapshot while attempting to "
214 "snapshot the GL surface.";
215 return nullptr;
216 }
217
218 return host_snapshot;
219}
220
222 return 0u;
223}
224
226 : TestGLSurface(std::make_shared<TestEGLContext>(), surface_size) {}
227
228TestGLSurface::TestGLSurface(std::shared_ptr<TestEGLContext> egl_context,
229 DlISize surface_size)
230 : TestGLOnscreenOnlySurface(std::move(egl_context), surface_size) {
231 {
232 const EGLint offscreen_surface_attributes[] = {
233 EGL_WIDTH, 1, //
234 EGL_HEIGHT, 1, //
235 EGL_NONE,
236 };
237 offscreen_surface_ = ::eglCreatePbufferSurface(
238 egl_context_->display, // display connection
239 egl_context_->config, // config
240 offscreen_surface_attributes // surface attributes
241 );
242 FML_CHECK(offscreen_surface_ != EGL_NO_SURFACE) << GetEGLError();
243 }
244}
245
247 auto result = ::eglDestroySurface(egl_context_->display, offscreen_surface_);
248 FML_CHECK(result == EGL_TRUE) << GetEGLError();
249}
250
252 auto result =
253 ::eglMakeCurrent(egl_context_->display, offscreen_surface_,
254 offscreen_surface_, egl_context_->offscreen_context);
255
256 if (result == EGL_FALSE) {
257 FML_LOG(ERROR) << "Could not make the resource context current. "
258 << GetEGLError();
259 }
260
261 return result == EGL_TRUE;
262}
263
264} // namespace flutter::testing
void * GetProcAddress(const char *name) const
std::shared_ptr< TestEGLContext > egl_context_
TestGLOnscreenOnlySurface(DlISize surface_size)
uint32_t GetFramebuffer(uint32_t width, uint32_t height) const
TestGLSurface(DlISize surface_size)
VkSurfaceKHR surface
Definition main.cc:65
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
std::string GetEGLError()
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
Definition ref_ptr.h:261
int32_t height
int32_t width
Type height
Definition size.h:29
Type width
Definition size.h:28