blob: b2d0b69d9a9cfb0d51c8e4ed5b719d48fb85541c [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.
#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
#include "flutter/fml/logging.h"
#include "flutter/impeller/toolkit/egl/surface.h"
#include "flutter/shell/gpu/gpu_surface_gl_impeller.h"
namespace flutter {
AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller(
const std::shared_ptr<AndroidContextGLImpeller>& android_context)
: android_context_(android_context) {
offscreen_surface_ = android_context_->CreateOffscreenSurface();
if (!offscreen_surface_) {
FML_DLOG(ERROR) << "Could not create offscreen surface.";
return;
}
// The onscreen surface will be acquired once the native window is set.
is_valid_ = true;
}
AndroidSurfaceGLImpeller::~AndroidSurfaceGLImpeller() = default;
// |AndroidSurface|
bool AndroidSurfaceGLImpeller::IsValid() const {
return is_valid_;
}
// |AndroidSurface|
std::unique_ptr<Surface> AndroidSurfaceGLImpeller::CreateGPUSurface(
GrDirectContext* gr_context) {
auto surface = std::make_unique<GPUSurfaceGLImpeller>(
this, // delegate
android_context_->GetImpellerContext(), // context
true // render to surface
);
if (!surface->IsValid()) {
return nullptr;
}
return surface;
}
// |AndroidSurface|
void AndroidSurfaceGLImpeller::TeardownOnScreenContext() {
GLContextClearCurrent();
onscreen_surface_.reset();
}
// |AndroidSurface|
bool AndroidSurfaceGLImpeller::OnScreenSurfaceResize(const SkISize& size) {
// The size is unused. It was added only for iOS where the sizes were
// necessary to re-create auxiliary buffers (stencil, depth, etc.).
return RecreateOnscreenSurfaceAndMakeOnscreenContextCurrent();
}
// |AndroidSurface|
bool AndroidSurfaceGLImpeller::ResourceContextMakeCurrent() {
if (!offscreen_surface_) {
return false;
}
return android_context_->ResourceContextMakeCurrent(offscreen_surface_.get());
}
// |AndroidSurface|
bool AndroidSurfaceGLImpeller::ResourceContextClearCurrent() {
return android_context_->ResourceContextClearCurrent();
}
// |AndroidSurface|
bool AndroidSurfaceGLImpeller::SetNativeWindow(
fml::RefPtr<AndroidNativeWindow> window) {
native_window_ = std::move(window);
return RecreateOnscreenSurfaceAndMakeOnscreenContextCurrent();
}
// |AndroidSurface|
std::unique_ptr<Surface> AndroidSurfaceGLImpeller::CreateSnapshotSurface() {
FML_UNREACHABLE();
}
// |AndroidSurface|
std::shared_ptr<impeller::Context>
AndroidSurfaceGLImpeller::GetImpellerContext() {
return android_context_->GetImpellerContext();
}
// |GPUSurfaceGLDelegate|
std::unique_ptr<GLContextResult>
AndroidSurfaceGLImpeller::GLContextMakeCurrent() {
return std::make_unique<GLContextDefaultResult>(OnGLContextMakeCurrent());
}
bool AndroidSurfaceGLImpeller::OnGLContextMakeCurrent() {
if (!onscreen_surface_) {
return false;
}
return android_context_->OnscreenContextMakeCurrent(onscreen_surface_.get());
}
// |GPUSurfaceGLDelegate|
bool AndroidSurfaceGLImpeller::GLContextClearCurrent() {
if (!onscreen_surface_) {
return false;
}
return android_context_->OnscreenContextClearCurrent();
}
// |GPUSurfaceGLDelegate|
SurfaceFrame::FramebufferInfo
AndroidSurfaceGLImpeller::GLContextFramebufferInfo() const {
auto info = SurfaceFrame::FramebufferInfo{};
info.supports_readback = true;
info.supports_partial_repaint = false;
return info;
}
// |GPUSurfaceGLDelegate|
void AndroidSurfaceGLImpeller::GLContextSetDamageRegion(
const std::optional<SkIRect>& region) {
// Not supported.
}
// |GPUSurfaceGLDelegate|
bool AndroidSurfaceGLImpeller::GLContextPresent(
const GLPresentInfo& present_info) {
// The FBO ID is superfluous and was introduced for iOS where the default
// framebuffer was not FBO0.
if (!onscreen_surface_) {
return false;
}
return onscreen_surface_->Present();
}
// |GPUSurfaceGLDelegate|
GLFBOInfo AndroidSurfaceGLImpeller::GLContextFBO(GLFrameInfo frame_info) const {
// FBO0 is the default window bound framebuffer in EGL environments.
return GLFBOInfo{
.fbo_id = 0,
};
}
// |GPUSurfaceGLDelegate|
sk_sp<const GrGLInterface> AndroidSurfaceGLImpeller::GetGLInterface() const {
return nullptr;
}
bool AndroidSurfaceGLImpeller::
RecreateOnscreenSurfaceAndMakeOnscreenContextCurrent() {
GLContextClearCurrent();
if (!native_window_) {
return false;
}
onscreen_surface_.reset();
auto onscreen_surface =
android_context_->CreateOnscreenSurface(native_window_->handle());
if (!onscreen_surface) {
FML_DLOG(ERROR) << "Could not create onscreen surface.";
return false;
}
onscreen_surface_ = std::move(onscreen_surface);
return OnGLContextMakeCurrent();
}
} // namespace flutter