13#include "third_party/skia/include/core/SkAlphaType.h"
14#include "third_party/skia/include/core/SkColorFilter.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/GrContextOptions.h"
20#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.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"
29#define GPU_GL_RGBA8 0x8058
30#define GPU_GL_RGBA4 0x8056
31#define GPU_GL_RGB565 0x8D62
45 if (!context_switch->GetResult()) {
47 <<
"Could not make the context current to set up the Gr context.";
54 auto context = GrDirectContexts::MakeGL(delegate->
GetGLInterface(), options);
57 FML_LOG(ERROR) <<
"Failed to set up Skia Gr context.";
69 bool render_to_surface)
71 context_owner_ =
true;
76 bool render_to_surface)
79 render_to_surface_(render_to_surface),
82 if (!context_switch->GetResult()) {
84 <<
"Could not make the context current to set up the Gr context.";
90 valid_ = gr_context !=
nullptr;
98 if (!context_switch->GetResult()) {
99 FML_LOG(ERROR) <<
"Could not make the context current to destroy the "
100 "GrDirectContext resources.";
104 onscreen_surface_ =
nullptr;
106 if (context_owner_) {
107 context_->releaseResourcesAndAbandonContext();
121#define RETURN_IF_RENDERABLE(x, y) \
122 if (context->colorTypeSupportedAsSurface((x))) { \
129 return kUnknown_SkColorType;
135 GrGLenum
format = kUnknown_SkColorType;
138 GrGLFramebufferInfo framebuffer_info = {};
139 framebuffer_info.fFBOID =
static_cast<GrGLuint
>(fbo);
140 framebuffer_info.fFormat =
format;
143 GrBackendRenderTargets::MakeGL(
size.width,
150 sk_sp<SkColorSpace> colorspace = SkColorSpace::MakeSRGB();
151 SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry);
153 return SkSurfaces::WrapBackendRenderTarget(
156 GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin,
163bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(
const DlISize&
size) {
164 if (onscreen_surface_ !=
nullptr &&
165 size.width == onscreen_surface_->width() &&
166 size.height == onscreen_surface_->height()) {
175 onscreen_surface_ =
nullptr;
178 if (
size.IsEmpty()) {
179 FML_LOG(ERROR) <<
"Cannot create surfaces of empty size.";
183 sk_sp<SkSurface> onscreen_surface;
185 GLFrameInfo frame_info = {
static_cast<uint32_t
>(
size.width),
186 static_cast<uint32_t
>(
size.height)};
187 const GLFBOInfo fbo_info = delegate_->
GLContextFBO(frame_info);
193 if (onscreen_surface ==
nullptr) {
196 FML_LOG(ERROR) <<
"Could not wrap onscreen surface.";
200 onscreen_surface_ = std::move(onscreen_surface);
201 fbo_id_ = fbo_info.fbo_id;
202 existing_damage_ = fbo_info.existing_damage;
215 if (delegate_ ==
nullptr) {
219 if (!context_switch->GetResult()) {
221 <<
"Could not make the context current to acquire the frame.";
229 if (!render_to_surface_) {
231 return std::make_unique<SurfaceFrame>(
232 nullptr, framebuffer_info,
242 AcquireRenderSurface(
size, root_surface_transformation);
248 surface->getCanvas()->setMatrix(
ToSkM44(root_surface_transformation));
251 [weak = weak_factory_.GetWeakPtr()](
const SurfaceFrame& surface_frame,
253 TRACE_EVENT0(
"flutter",
"GrDirectContext::flushAndSubmit");
255 weak->context_->flushAndSubmit();
261 [weak = weak_factory_.GetWeakPtr()](
const SurfaceFrame& surface_frame) {
262 return weak ? weak->PresentSurface(surface_frame) :
false;
269 return std::make_unique<SurfaceFrame>(
surface, framebuffer_info,
270 encode_callback, submit_callback,
size,
271 std::move(context_switch));
274bool GPUSurfaceGLSkia::PresentSurface(
const SurfaceFrame& frame) {
275 if (delegate_ ==
nullptr || context_ ==
nullptr) {
281 GLPresentInfo present_info = {
293 DlISize(onscreen_surface_->width(), onscreen_surface_->height());
295 GLFrameInfo frame_info = {
static_cast<uint32_t
>(current_size.width),
296 static_cast<uint32_t
>(current_size.height)};
300 const GLFBOInfo fbo_info = delegate_->
GLContextFBO(frame_info);
301 auto new_onscreen_surface =
307 if (!new_onscreen_surface) {
311 onscreen_surface_ = std::move(new_onscreen_surface);
312 fbo_id_ = fbo_info.fbo_id;
313 existing_damage_ = fbo_info.existing_damage;
319sk_sp<SkSurface> GPUSurfaceGLSkia::AcquireRenderSurface(
320 const DlISize& untransformed_size,
321 const DlMatrix& root_surface_transformation) {
322 const auto transformed_rect =
326 const DlISize transformed_size =
329 if (!CreateOrUpdateSurfaces(transformed_size)) {
333 return onscreen_surface_;
338 return context_.get();
Developer-facing API for rendering anything within the engine.
virtual bool AllowsDrawingWhenGpuDisabled() const
virtual std::unique_ptr< GLContextResult > GLContextMakeCurrent()=0
virtual bool GLContextClearCurrent()=0
virtual bool GLContextPresent(const GLPresentInfo &present_info)=0
virtual void GLContextSetDamageRegion(const std::optional< DlIRect > ®ion)
virtual sk_sp< const GrGLInterface > GetGLInterface() const
virtual bool GLContextFBOResetAfterPresent() const
virtual SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const
virtual GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const =0
virtual DlMatrix GLContextSurfaceTransformation() const
GrDirectContext * GetContext() override
DlMatrix GetRootTransformation() const override
bool AllowsDrawingWhenGpuDisabled() const override
bool ClearRenderContext() override
static sk_sp< GrDirectContext > MakeGLContext(GPUSurfaceGLDelegate *delegate)
GPUSurfaceGLSkia(GPUSurfaceGLDelegate *delegate, bool render_to_surface)
~GPUSurfaceGLSkia() override
std::unique_ptr< GLContextResult > MakeRenderContextCurrent() override
std::unique_ptr< SurfaceFrame > AcquireFrame(const DlISize &size) override
static PersistentCache * GetCacheForProcess()
size_t PrecompileKnownSkSLs(GrDirectContext *context) const
Precompile SkSLs packaged with the application and gathered during previous runs in the given context...
std::function< bool(SurfaceFrame &surface_frame, DlCanvas *canvas)> EncodeCallback
std::function< bool(SurfaceFrame &surface_frame)> SubmitCallback
const SubmitInfo & submit_info() const
uint32_t uint32_t * format
#define FML_LOG(severity)
#define RETURN_IF_RENDERABLE(x, y)
static SkColorType FirstSupportedColorType(GrDirectContext *context, GrGLenum *format)
impeller::Matrix DlMatrix
impeller::ISize32 DlISize
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
static sk_sp< SkSurface > WrapOnscreenSurface(GrDirectContext *context, const DlISize &size, intptr_t fbo)
GrContextOptions MakeDefaultContextOptions(ContextType type, std::optional< GrBackendApi > api)
Initializes GrContextOptions with values suitable for Flutter. The options can be further tweaked bef...
static const size_t kGrCacheMaxByteSize
@ kRender
The context is used to render to a texture or renderbuffer.
SkM44 ToSkM44(const DlMatrix &matrix)
std::optional< DlIRect > existing_damage
std::optional< DlIRect > frame_damage
std::optional< DlIRect > buffer_damage
std::optional< fml::TimePoint > presentation_time
A 4x4 matrix using column-major storage.
RoundOut(const TRect< U > &r)
constexpr TRect TransformAndClipBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle, clipped against the near clippin...
static constexpr TRect MakeSize(const TSize< U > &size)
#define TRACE_EVENT0(category_group, name)