blob: e1c5bde675499071f7392a80fcc54c8c946a4627 [file] [log] [blame]
// 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.
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/gpu/gpu_surface_gl.h"
#import "flutter/shell/platform/darwin/ios/ios_context_gl.h"
namespace flutter {
static IOSContextGL* CastToGLContext(const std::shared_ptr<IOSContext>& context) {
return reinterpret_cast<IOSContextGL*>(context.get());
}
IOSSurfaceGL::IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer,
std::shared_ptr<IOSContext> context)
: IOSSurface(context) {
render_target_ = CastToGLContext(context)->CreateRenderTarget(std::move(layer));
}
IOSSurfaceGL::~IOSSurfaceGL() = default;
// |IOSSurface|
bool IOSSurfaceGL::IsValid() const {
return render_target_->IsValid();
}
// |IOSSurface|
void IOSSurfaceGL::UpdateStorageSizeIfNecessary() {
if (IsValid()) {
render_target_->UpdateStorageSizeIfNecessary();
}
}
// |IOSSurface|
std::unique_ptr<Surface> IOSSurfaceGL::CreateGPUSurface(GrDirectContext* gr_context) {
if (gr_context) {
return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
} else {
IOSContextGL* gl_context = CastToGLContext(GetContext());
sk_sp<GrDirectContext> context = gl_context->GetMainContext();
if (!context) {
context = GPUSurfaceGL::MakeGLContext(this);
gl_context->SetMainContext(context);
}
return std::make_unique<GPUSurfaceGL>(context, this, true);
}
}
// |GPUSurfaceGLDelegate|
intptr_t IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
return IsValid() ? render_target_->GetFramebuffer() : GL_NONE;
}
// |GPUSurfaceGLDelegate|
bool IOSSurfaceGL::SurfaceSupportsReadback() const {
// The onscreen surface wraps a GL renderbuffer, which is extremely slow to read on iOS.
// Certain filter effects, in particular BackdropFilter, require making a copy of
// the current destination. For performance, the iOS surface will specify that it
// does not support readback so that the engine compositor can implement a workaround
// such as rendering the scene to an offscreen surface or Skia saveLayer.
return false;
}
// |GPUSurfaceGLDelegate|
std::unique_ptr<GLContextResult> IOSSurfaceGL::GLContextMakeCurrent() {
if (!IsValid()) {
return std::make_unique<GLContextDefaultResult>(false);
}
bool update_if_necessary = render_target_->UpdateStorageSizeIfNecessary();
if (!update_if_necessary) {
return std::make_unique<GLContextDefaultResult>(false);
}
return GetContext()->MakeCurrent();
}
// |GPUSurfaceGLDelegate|
bool IOSSurfaceGL::GLContextClearCurrent() {
// |GLContextMakeCurrent| should handle the scope of the gl context.
return true;
}
// |GPUSurfaceGLDelegate|
bool IOSSurfaceGL::GLContextPresent(uint32_t fbo_id) {
TRACE_EVENT0("flutter", "IOSSurfaceGL::GLContextPresent");
return IsValid() && render_target_->PresentRenderBuffer();
}
// |GPUSurfaceGLDelegate|
bool IOSSurfaceGL::AllowsDrawingWhenGpuDisabled() const {
return false;
}
} // namespace flutter