// 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.h" #include #include "flutter/fml/logging.h" #include "flutter/fml/memory/ref_ptr.h" namespace flutter { AndroidSurfaceGL::AndroidSurfaceGL( std::shared_ptr android_context) : native_window_(nullptr), onscreen_surface_(nullptr), offscreen_surface_(nullptr) { android_context_ = std::static_pointer_cast(android_context); // Acquire the offscreen surface. offscreen_surface_ = android_context_->CreateOffscreenSurface(); if (offscreen_surface_ == EGL_NO_SURFACE) { offscreen_surface_ = nullptr; } external_view_embedder_ = std::make_unique(); } AndroidSurfaceGL::~AndroidSurfaceGL() { if (offscreen_surface_) { android_context_->TeardownSurface(offscreen_surface_); offscreen_surface_ = nullptr; } if (onscreen_surface_) { android_context_->TeardownSurface(onscreen_surface_); onscreen_surface_ = nullptr; } } void AndroidSurfaceGL::TeardownOnScreenContext() { android_context_->ClearCurrent(); } bool AndroidSurfaceGL::IsValid() const { return offscreen_surface_ && android_context_->IsValid(); } std::unique_ptr AndroidSurfaceGL::CreateGPUSurface( GrContext* gr_context) { if (gr_context) { return std::make_unique(sk_ref_sp(gr_context), this, true); } return std::make_unique(this, true); } bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) { FML_DCHECK(IsValid()); FML_DCHECK(onscreen_surface_); FML_DCHECK(native_window_); if (size == android_context_->GetSize(onscreen_surface_)) { return true; } android_context_->ClearCurrent(); android_context_->TeardownSurface(onscreen_surface_); onscreen_surface_ = android_context_->CreateOnscreenSurface(native_window_); if (!onscreen_surface_ || onscreen_surface_ == EGL_NO_SURFACE) { FML_LOG(ERROR) << "Unable to create EGL window surface on resize."; return false; } android_context_->MakeCurrent(onscreen_surface_); return true; } bool AndroidSurfaceGL::ResourceContextMakeCurrent() { FML_DCHECK(IsValid()); return android_context_->ResourceMakeCurrent(offscreen_surface_); } bool AndroidSurfaceGL::ResourceContextClearCurrent() { FML_DCHECK(IsValid()); return android_context_->ClearCurrent(); } bool AndroidSurfaceGL::SetNativeWindow( fml::RefPtr window) { FML_DCHECK(IsValid()); FML_DCHECK(window); native_window_ = window; // Create the onscreen surface. onscreen_surface_ = android_context_->CreateOnscreenSurface(window); if (onscreen_surface_ == EGL_NO_SURFACE) { return false; } return true; } std::unique_ptr AndroidSurfaceGL::GLContextMakeCurrent() { FML_DCHECK(IsValid()); FML_DCHECK(onscreen_surface_); auto default_context_result = std::make_unique( android_context_->MakeCurrent(onscreen_surface_)); return std::move(default_context_result); } bool AndroidSurfaceGL::GLContextClearCurrent() { FML_DCHECK(IsValid()); return android_context_->ClearCurrent(); } bool AndroidSurfaceGL::GLContextPresent() { FML_DCHECK(IsValid()); FML_DCHECK(onscreen_surface_); return android_context_->SwapBuffers(onscreen_surface_); } intptr_t AndroidSurfaceGL::GLContextFBO() const { FML_DCHECK(IsValid()); // The default window bound framebuffer on Android. return 0; } // |GPUSurfaceGLDelegate| ExternalViewEmbedder* AndroidSurfaceGL::GetExternalViewEmbedder() { return external_view_embedder_.get(); } } // namespace flutter