mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Remove the OpenGL backend on iOS (flutter/engine#34913)
This commit is contained in:
parent
76aea382bf
commit
352bf98b3f
@ -1781,34 +1781,24 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_i
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/framework/module.modulemap
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_gl.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_gl.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_impeller.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_skia.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_skia.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_software.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_software.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_gl.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_gl.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_metal.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_metal.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_view_embedder.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_view_embedder.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_render_target_gl.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal_skia.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal_skia.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_switchable_gl_context.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/ios_switchable_gl_context.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios_test.mm
|
||||
|
||||
@ -16,7 +16,7 @@ _flutter_framework_dir = "$root_out_dir/Flutter.framework"
|
||||
|
||||
shell_gpu_configuration("ios_gpu_configuration") {
|
||||
enable_software = true
|
||||
enable_gl = true
|
||||
enable_gl = false
|
||||
enable_vulkan = false
|
||||
enable_metal = shell_enable_metal
|
||||
}
|
||||
@ -111,24 +111,14 @@ source_set("flutter_framework_source") {
|
||||
"framework/Source/vsync_waiter_ios.mm",
|
||||
"ios_context.h",
|
||||
"ios_context.mm",
|
||||
"ios_context_gl.h",
|
||||
"ios_context_gl.mm",
|
||||
"ios_context_software.h",
|
||||
"ios_context_software.mm",
|
||||
"ios_external_texture_gl.h",
|
||||
"ios_external_texture_gl.mm",
|
||||
"ios_external_view_embedder.h",
|
||||
"ios_external_view_embedder.mm",
|
||||
"ios_render_target_gl.h",
|
||||
"ios_render_target_gl.mm",
|
||||
"ios_surface.h",
|
||||
"ios_surface.mm",
|
||||
"ios_surface_gl.h",
|
||||
"ios_surface_gl.mm",
|
||||
"ios_surface_software.h",
|
||||
"ios_surface_software.mm",
|
||||
"ios_switchable_gl_context.h",
|
||||
"ios_switchable_gl_context.mm",
|
||||
"platform_message_handler_ios.h",
|
||||
"platform_message_handler_ios.mm",
|
||||
"platform_view_ios.h",
|
||||
@ -185,7 +175,6 @@ source_set("flutter_framework_source") {
|
||||
"AudioToolbox.framework",
|
||||
"CoreMedia.framework",
|
||||
"CoreVideo.framework",
|
||||
"OpenGLES.framework",
|
||||
"QuartzCore.framework",
|
||||
"UIKit.framework",
|
||||
]
|
||||
|
||||
@ -11,9 +11,7 @@
|
||||
|
||||
#include "flutter/fml/memory/weak_ptr.h"
|
||||
#include "flutter/shell/common/shell.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "flutter/shell/common/platform_view.h"
|
||||
#include "flutter/shell/common/rasterizer.h"
|
||||
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_software.h"
|
||||
#include "third_party/skia/include/utils/mac/SkCGUtils.h"
|
||||
|
||||
@ -46,8 +45,7 @@
|
||||
- (instancetype)initWithContentsScale:(CGFloat)contentsScale {
|
||||
self = [self init];
|
||||
|
||||
if ([self.layer isKindOfClass:NSClassFromString(@"CAEAGLLayer")] ||
|
||||
[self.layer isKindOfClass:NSClassFromString(@"CAMetalLayer")]) {
|
||||
if ([self.layer isKindOfClass:NSClassFromString(@"CAMetalLayer")]) {
|
||||
self.layer.allowsGroupOpacity = NO;
|
||||
self.layer.contentsScale = contentsScale;
|
||||
self.layer.rasterizationScale = contentsScale;
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
|
||||
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
|
||||
|
||||
@implementation UIView (FirstResponder)
|
||||
- (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "flutter/shell/common/platform_view.h"
|
||||
#include "flutter/shell/common/rasterizer.h"
|
||||
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_software.h"
|
||||
#include "third_party/skia/include/utils/mac/SkCGUtils.h"
|
||||
|
||||
@ -54,8 +53,7 @@
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
if ([self.layer isKindOfClass:NSClassFromString(@"CAEAGLLayer")] ||
|
||||
[self.layer isKindOfClass:NSClassFromString(@"CAMetalLayer")]) {
|
||||
if ([self.layer isKindOfClass:NSClassFromString(@"CAMetalLayer")]) {
|
||||
CGFloat screenScale = [UIScreen mainScreen].scale;
|
||||
self.layer.allowsGroupOpacity = YES;
|
||||
self.layer.contentsScale = screenScale;
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context.h"
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_software.h"
|
||||
|
||||
#if SHELL_ENABLE_METAL
|
||||
@ -23,8 +22,6 @@ std::unique_ptr<IOSContext> IOSContext::Create(IOSRenderingAPI api,
|
||||
IOSRenderingBackend backend,
|
||||
MsaaSampleCount msaa_samples) {
|
||||
switch (api) {
|
||||
case IOSRenderingAPI::kOpenGLES:
|
||||
return std::make_unique<IOSContextGL>();
|
||||
case IOSRenderingAPI::kSoftware:
|
||||
return std::make_unique<IOSContextSoftware>();
|
||||
#if SHELL_ENABLE_METAL
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_GL_CONTEXT_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_GL_CONTEXT_H_
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#include "flutter/shell/common/platform_view.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_render_target_gl.h"
|
||||
|
||||
@class CAEAGLLayer;
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class IOSContextGL final : public IOSContext {
|
||||
public:
|
||||
IOSContextGL();
|
||||
|
||||
// |IOSContext|
|
||||
~IOSContextGL() override;
|
||||
|
||||
std::unique_ptr<IOSRenderTargetGL> CreateRenderTarget(fml::scoped_nsobject<CAEAGLLayer> layer);
|
||||
|
||||
void SetMainContext(const sk_sp<GrDirectContext>& main_context);
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> CreateResourceContext() override;
|
||||
|
||||
// |IOSContext|
|
||||
std::unique_ptr<GLContextResult> MakeCurrent() override;
|
||||
|
||||
// |IOSContext|
|
||||
std::unique_ptr<Texture> CreateExternalTexture(
|
||||
int64_t texture_id,
|
||||
fml::scoped_nsobject<NSObject<FlutterTexture>> texture) override;
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> GetMainContext() const override;
|
||||
|
||||
private:
|
||||
fml::scoped_nsobject<EAGLContext> context_;
|
||||
fml::scoped_nsobject<EAGLContext> resource_context_;
|
||||
sk_sp<GrDirectContext> main_context_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSContextGL);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_GL_CONTEXT_H_
|
||||
@ -1,73 +0,0 @@
|
||||
// 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_context_gl.h"
|
||||
|
||||
#import <OpenGLES/EAGL.h>
|
||||
|
||||
#include "flutter/shell/common/shell_io_manager.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_gl_skia.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_external_texture_gl.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSContextGL::IOSContextGL() : IOSContext(MsaaSampleCount::kNone) {
|
||||
resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]);
|
||||
if (resource_context_ != nullptr) {
|
||||
context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
|
||||
sharegroup:resource_context_.get().sharegroup]);
|
||||
} else {
|
||||
resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]);
|
||||
context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
|
||||
sharegroup:resource_context_.get().sharegroup]);
|
||||
}
|
||||
}
|
||||
|
||||
IOSContextGL::~IOSContextGL() {
|
||||
if (main_context_) {
|
||||
main_context_->releaseResourcesAndAbandonContext();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<IOSRenderTargetGL> IOSContextGL::CreateRenderTarget(
|
||||
fml::scoped_nsobject<CAEAGLLayer> layer) {
|
||||
return std::make_unique<IOSRenderTargetGL>(std::move(layer), context_);
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> IOSContextGL::CreateResourceContext() {
|
||||
if (![EAGLContext setCurrentContext:resource_context_.get()]) {
|
||||
FML_DLOG(INFO) << "Could not make resource context current on IO thread. Async texture uploads "
|
||||
"will be disabled. On Simulators, this is expected.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ShellIOManager::CreateCompatibleResourceLoadingContext(
|
||||
GrBackend::kOpenGL_GrBackend, GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface());
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> IOSContextGL::GetMainContext() const {
|
||||
return main_context_;
|
||||
}
|
||||
|
||||
void IOSContextGL::SetMainContext(const sk_sp<GrDirectContext>& main_context) {
|
||||
main_context_ = main_context;
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
std::unique_ptr<GLContextResult> IOSContextGL::MakeCurrent() {
|
||||
return std::make_unique<GLContextSwitch>(
|
||||
std::make_unique<IOSSwitchableGLContext>(context_.get()));
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
std::unique_ptr<Texture> IOSContextGL::CreateExternalTexture(
|
||||
int64_t texture_id,
|
||||
fml::scoped_nsobject<NSObject<FlutterTexture>> texture) {
|
||||
return std::make_unique<IOSExternalTextureGL>(texture_id, std::move(texture), context_);
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
@ -1,76 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_IOS_EXTERNAL_TEXTURE_GL_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_IOS_EXTERNAL_TEXTURE_GL_H_
|
||||
|
||||
#include "flutter/common/graphics/texture.h"
|
||||
#include "flutter/fml/platform/darwin/cf_utils.h"
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class IOSExternalTextureGL final : public Texture {
|
||||
public:
|
||||
IOSExternalTextureGL(int64_t textureId,
|
||||
NSObject<FlutterTexture>* externalTexture,
|
||||
fml::scoped_nsobject<EAGLContext> context);
|
||||
|
||||
// |Texture|
|
||||
~IOSExternalTextureGL() override;
|
||||
|
||||
private:
|
||||
bool new_frame_ready_ = false;
|
||||
fml::scoped_nsobject<NSObject<FlutterTexture>> external_texture_;
|
||||
fml::CFRef<CVOpenGLESTextureCacheRef> cache_ref_;
|
||||
fml::CFRef<CVOpenGLESTextureRef> texture_ref_;
|
||||
fml::CFRef<CVPixelBufferRef> buffer_ref_;
|
||||
OSType pixel_format_ = 0;
|
||||
fml::CFRef<CVOpenGLESTextureRef> y_texture_ref_;
|
||||
fml::CFRef<CVOpenGLESTextureRef> uv_texture_ref_;
|
||||
fml::scoped_nsobject<EAGLContext> context_;
|
||||
|
||||
// |Texture|
|
||||
void Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) override;
|
||||
|
||||
// |Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
// |Texture|
|
||||
void OnGrContextDestroyed() override;
|
||||
|
||||
// |Texture|
|
||||
void MarkNewFrameAvailable() override;
|
||||
|
||||
// |Texture|
|
||||
void OnTextureUnregistered() override;
|
||||
|
||||
void CreateTextureFromPixelBuffer();
|
||||
|
||||
void EnsureTextureCacheExists();
|
||||
|
||||
bool NeedUpdateTexture(bool freeze);
|
||||
|
||||
bool IsTexturesAvailable() const;
|
||||
|
||||
void CreateYUVTexturesFromPixelBuffer();
|
||||
|
||||
void CreateRGBATextureFromPixelBuffer();
|
||||
|
||||
sk_sp<SkImage> CreateImageFromYUVTextures(GrDirectContext* context, const SkRect& bounds);
|
||||
|
||||
sk_sp<SkImage> CreateImageFromRGBATexture(GrDirectContext* context, const SkRect& bounds);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSExternalTextureGL);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_IOS_EXTERNAL_TEXTURE_GL_H_
|
||||
@ -1,201 +0,0 @@
|
||||
// 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_external_texture_gl.h"
|
||||
|
||||
#import <OpenGLES/EAGL.h>
|
||||
#import <OpenGLES/ES2/gl.h>
|
||||
#import <OpenGLES/ES2/glext.h>
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
|
||||
#include "third_party/skia/include/core/SkColorSpace.h"
|
||||
#include "third_party/skia/include/core/SkSurface.h"
|
||||
#include "third_party/skia/include/core/SkYUVAInfo.h"
|
||||
#include "third_party/skia/include/gpu/GrBackendSurface.h"
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
#include "third_party/skia/include/gpu/GrYUVABackendTextures.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSExternalTextureGL::IOSExternalTextureGL(int64_t textureId,
|
||||
NSObject<FlutterTexture>* externalTexture,
|
||||
fml::scoped_nsobject<EAGLContext> context)
|
||||
: Texture(textureId),
|
||||
external_texture_(fml::scoped_nsobject<NSObject<FlutterTexture>>([externalTexture retain])),
|
||||
context_(context) {
|
||||
FML_DCHECK(external_texture_);
|
||||
}
|
||||
|
||||
IOSExternalTextureGL::~IOSExternalTextureGL() = default;
|
||||
|
||||
void IOSExternalTextureGL::EnsureTextureCacheExists() {
|
||||
if (!cache_ref_) {
|
||||
CVOpenGLESTextureCacheRef cache;
|
||||
CVReturn err =
|
||||
CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, context_.get(), NULL, &cache);
|
||||
if (err == noErr) {
|
||||
cache_ref_.Reset(cache);
|
||||
} else {
|
||||
FML_LOG(WARNING) << "Failed to create GLES texture cache: " << err;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::CreateTextureFromPixelBuffer() {
|
||||
if (buffer_ref_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (pixel_format_ == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
||||
pixel_format_ == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
|
||||
CreateYUVTexturesFromPixelBuffer();
|
||||
} else {
|
||||
CreateRGBATextureFromPixelBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::CreateRGBATextureFromPixelBuffer() {
|
||||
CVOpenGLESTextureRef texture;
|
||||
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(
|
||||
kCFAllocatorDefault, cache_ref_, buffer_ref_, /*textureAttributes=*/nullptr, GL_TEXTURE_2D,
|
||||
GL_RGBA, static_cast<int>(CVPixelBufferGetWidth(buffer_ref_)),
|
||||
static_cast<int>(CVPixelBufferGetHeight(buffer_ref_)), GL_BGRA, GL_UNSIGNED_BYTE, 0,
|
||||
&texture);
|
||||
if (err != noErr) {
|
||||
FML_LOG(WARNING) << "Could not create texture from pixel buffer: " << err;
|
||||
} else {
|
||||
texture_ref_.Reset(texture);
|
||||
}
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::CreateYUVTexturesFromPixelBuffer() {
|
||||
size_t width = CVPixelBufferGetWidth(buffer_ref_);
|
||||
size_t height = CVPixelBufferGetHeight(buffer_ref_);
|
||||
{
|
||||
CVOpenGLESTextureRef yTexture;
|
||||
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(
|
||||
kCFAllocatorDefault, cache_ref_, buffer_ref_, /*textureAttributes=*/nullptr, GL_TEXTURE_2D,
|
||||
GL_LUMINANCE, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &yTexture);
|
||||
if (err != noErr) {
|
||||
FML_DCHECK(yTexture) << "Could not create texture from pixel buffer: " << err;
|
||||
} else {
|
||||
y_texture_ref_.Reset(yTexture);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CVOpenGLESTextureRef uvTexture;
|
||||
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(
|
||||
kCFAllocatorDefault, cache_ref_, buffer_ref_, /*textureAttributes=*/nullptr, GL_TEXTURE_2D,
|
||||
GL_LUMINANCE_ALPHA, width / 2, height / 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1,
|
||||
&uvTexture);
|
||||
if (err != noErr) {
|
||||
FML_DCHECK(uvTexture) << "Could not create texture from pixel buffer: " << err;
|
||||
} else {
|
||||
uv_texture_ref_.Reset(uvTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<SkImage> IOSExternalTextureGL::CreateImageFromRGBATexture(GrDirectContext* context,
|
||||
const SkRect& bounds) {
|
||||
GrGLTextureInfo textureInfo = {CVOpenGLESTextureGetTarget(texture_ref_),
|
||||
CVOpenGLESTextureGetName(texture_ref_), GL_RGBA8_OES};
|
||||
GrBackendTexture backendTexture(bounds.width(), bounds.height(), GrMipMapped::kNo, textureInfo);
|
||||
sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType,
|
||||
/*imageColorSpace=*/nullptr);
|
||||
return image;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> IOSExternalTextureGL::CreateImageFromYUVTextures(GrDirectContext* context,
|
||||
const SkRect& bounds) {
|
||||
GrBackendTexture textures[2];
|
||||
GrGLTextureInfo yTextureInfo = {CVOpenGLESTextureGetTarget(y_texture_ref_),
|
||||
CVOpenGLESTextureGetName(y_texture_ref_), GL_LUMINANCE8_EXT};
|
||||
textures[0] = GrBackendTexture(bounds.width(), bounds.height(), GrMipMapped::kNo, yTextureInfo);
|
||||
GrGLTextureInfo uvTextureInfo = {CVOpenGLESTextureGetTarget(uv_texture_ref_),
|
||||
CVOpenGLESTextureGetName(uv_texture_ref_),
|
||||
GL_LUMINANCE8_ALPHA8_EXT};
|
||||
textures[1] = GrBackendTexture(bounds.width(), bounds.height(), GrMipMapped::kNo, uvTextureInfo);
|
||||
|
||||
SkYUVAInfo yuvaInfo(textures[0].dimensions(), SkYUVAInfo::PlaneConfig::kY_UV,
|
||||
SkYUVAInfo::Subsampling::k444, kRec601_SkYUVColorSpace);
|
||||
GrYUVABackendTextures yuvaBackendTextures(yuvaInfo, textures, kTopLeft_GrSurfaceOrigin);
|
||||
sk_sp<SkImage> image = SkImage::MakeFromYUVATextures(context, yuvaBackendTextures,
|
||||
/*imageColorSpace=*/nullptr);
|
||||
return image;
|
||||
}
|
||||
|
||||
bool IOSExternalTextureGL::IsTexturesAvailable() const {
|
||||
return ((pixel_format_ == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
||||
pixel_format_ == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) &&
|
||||
(y_texture_ref_ && uv_texture_ref_)) ||
|
||||
(pixel_format_ == kCVPixelFormatType_32BGRA && texture_ref_);
|
||||
}
|
||||
|
||||
bool IOSExternalTextureGL::NeedUpdateTexture(bool freeze) {
|
||||
// Update texture if `texture_ref_` is reset to `nullptr` when GrContext
|
||||
// is destroyed or new frame is ready.
|
||||
return (!freeze && new_frame_ready_) || !IsTexturesAvailable();
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) {
|
||||
EnsureTextureCacheExists();
|
||||
if (NeedUpdateTexture(freeze)) {
|
||||
auto pixelBuffer = [external_texture_.get() copyPixelBuffer];
|
||||
if (pixelBuffer) {
|
||||
buffer_ref_.Reset(pixelBuffer);
|
||||
pixel_format_ = CVPixelBufferGetPixelFormatType(buffer_ref_);
|
||||
}
|
||||
CreateTextureFromPixelBuffer();
|
||||
new_frame_ready_ = false;
|
||||
}
|
||||
if (!IsTexturesAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> image = nullptr;
|
||||
if (pixel_format_ == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
||||
pixel_format_ == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
|
||||
image = CreateImageFromYUVTextures(context, bounds);
|
||||
} else {
|
||||
image = CreateImageFromRGBATexture(context, bounds);
|
||||
}
|
||||
|
||||
FML_DCHECK(image) << "Failed to create SkImage from Texture.";
|
||||
if (image) {
|
||||
canvas.drawImage(image, bounds.x(), bounds.y(), sampling, paint);
|
||||
}
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::OnGrContextCreated() {
|
||||
// Re-create texture from pixel buffer that was saved before
|
||||
// OnGrContextDestroyed gets called.
|
||||
// https://github.com/flutter/flutter/issues/30491
|
||||
EnsureTextureCacheExists();
|
||||
CreateTextureFromPixelBuffer();
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::OnGrContextDestroyed() {
|
||||
texture_ref_.Reset(nullptr);
|
||||
cache_ref_.Reset(nullptr);
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::MarkNewFrameAvailable() {
|
||||
new_frame_ready_ = true;
|
||||
}
|
||||
|
||||
void IOSExternalTextureGL::OnTextureUnregistered() {
|
||||
if ([external_texture_ respondsToSelector:@selector(onTextureUnregistered:)]) {
|
||||
[external_texture_ onTextureUnregistered:external_texture_];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
@ -1,49 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_RENDER_TARGET_GL_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_RENDER_TARGET_GL_H_
|
||||
|
||||
#import <OpenGLES/EAGL.h>
|
||||
#import <OpenGLES/ES2/gl.h>
|
||||
#import <OpenGLES/ES2/glext.h>
|
||||
#import <QuartzCore/CAEAGLLayer.h>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#include "flutter/shell/common/platform_view.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_switchable_gl_context.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class IOSRenderTargetGL {
|
||||
public:
|
||||
IOSRenderTargetGL(fml::scoped_nsobject<CAEAGLLayer> layer,
|
||||
fml::scoped_nsobject<EAGLContext> context_);
|
||||
|
||||
~IOSRenderTargetGL();
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
bool PresentRenderBuffer() const;
|
||||
|
||||
intptr_t GetFramebuffer() const;
|
||||
|
||||
bool UpdateStorageSizeIfNecessary();
|
||||
|
||||
private:
|
||||
fml::scoped_nsobject<CAEAGLLayer> layer_;
|
||||
fml::scoped_nsobject<EAGLContext> context_;
|
||||
GLuint framebuffer_ = GL_NONE;
|
||||
GLuint colorbuffer_ = GL_NONE;
|
||||
GLint storage_size_width_ = GL_NONE;
|
||||
GLint storage_size_height_ = GL_NONE;
|
||||
bool valid_ = false;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSRenderTargetGL);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_RENDER_TARGET_GL_H_
|
||||
@ -1,140 +0,0 @@
|
||||
// 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_render_target_gl.h"
|
||||
|
||||
#include <UIKit/UIKit.h>
|
||||
|
||||
#include "flutter/fml/trace_event.h"
|
||||
#include "third_party/skia/include/gpu/GrContextOptions.h"
|
||||
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSRenderTargetGL::IOSRenderTargetGL(fml::scoped_nsobject<CAEAGLLayer> layer,
|
||||
fml::scoped_nsobject<EAGLContext> context)
|
||||
: layer_(std::move(layer)), context_(context) {
|
||||
FML_DCHECK(layer_ != nullptr);
|
||||
FML_DCHECK(context_ != nullptr);
|
||||
|
||||
if (@available(iOS 9.0, *)) {
|
||||
[layer_ setPresentsWithTransaction:YES];
|
||||
}
|
||||
auto context_switch = GLContextSwitch(std::make_unique<IOSSwitchableGLContext>(context_.get()));
|
||||
[[maybe_unused]] bool context_current = context_switch.GetResult();
|
||||
|
||||
FML_DCHECK(context_current);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
// Generate the framebuffer
|
||||
|
||||
glGenFramebuffers(1, &framebuffer_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
FML_DCHECK(framebuffer_ != GL_NONE);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
// Setup color attachment
|
||||
|
||||
glGenRenderbuffers(1, &colorbuffer_);
|
||||
FML_DCHECK(colorbuffer_ != GL_NONE);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
NSString* drawableColorFormat = kEAGLColorFormatRGBA8;
|
||||
layer_.get().drawableProperties = @{
|
||||
kEAGLDrawablePropertyColorFormat : drawableColorFormat,
|
||||
kEAGLDrawablePropertyRetainedBacking : @(NO),
|
||||
};
|
||||
|
||||
valid_ = true;
|
||||
}
|
||||
|
||||
IOSRenderTargetGL::~IOSRenderTargetGL() {
|
||||
auto context_switch = GLContextSwitch(std::make_unique<IOSSwitchableGLContext>(context_.get()));
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
// Deletes on GL_NONEs are ignored
|
||||
glDeleteFramebuffers(1, &framebuffer_);
|
||||
glDeleteRenderbuffers(1, &colorbuffer_);
|
||||
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// |IOSRenderTarget|
|
||||
bool IOSRenderTargetGL::IsValid() const {
|
||||
return valid_;
|
||||
}
|
||||
|
||||
// |IOSRenderTarget|
|
||||
intptr_t IOSRenderTargetGL::GetFramebuffer() const {
|
||||
return framebuffer_;
|
||||
}
|
||||
|
||||
// |IOSRenderTarget|
|
||||
bool IOSRenderTargetGL::PresentRenderBuffer() const {
|
||||
const GLenum discards[] = {
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_STENCIL_ATTACHMENT,
|
||||
};
|
||||
|
||||
glDiscardFramebufferEXT(GL_FRAMEBUFFER, sizeof(discards) / sizeof(GLenum), discards);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer_);
|
||||
auto current_context = [EAGLContext currentContext];
|
||||
FML_DCHECK(current_context != nullptr);
|
||||
return [current_context presentRenderbuffer:GL_RENDERBUFFER];
|
||||
}
|
||||
|
||||
// |IOSRenderTarget|
|
||||
bool IOSRenderTargetGL::UpdateStorageSizeIfNecessary() {
|
||||
const CGSize layer_size = [layer_.get() bounds].size;
|
||||
const CGFloat contents_scale = layer_.get().contentsScale;
|
||||
const GLint size_width = layer_size.width * contents_scale;
|
||||
const GLint size_height = layer_size.height * contents_scale;
|
||||
|
||||
if (size_width == storage_size_width_ && size_height == storage_size_height_) {
|
||||
// Nothing to do since the storage size is already consistent with the layer.
|
||||
return true;
|
||||
}
|
||||
TRACE_EVENT_INSTANT0("flutter", "IOSRenderTargetGL::UpdateStorageSizeIfNecessary");
|
||||
FML_DLOG(INFO) << "Updating render buffer storage size.";
|
||||
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
auto context_switch = GLContextSwitch(std::make_unique<IOSSwitchableGLContext>(context_.get()));
|
||||
if (!context_switch.GetResult()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
auto current_context = [EAGLContext currentContext];
|
||||
if (![current_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer_.get()]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fetch the dimensions of the color buffer whose backing was just updated.
|
||||
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &storage_size_width_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &storage_size_height_);
|
||||
FML_DCHECK(glGetError() == GL_NO_ERROR);
|
||||
|
||||
FML_DCHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
@ -4,7 +4,6 @@
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_software.h"
|
||||
|
||||
#include "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
|
||||
@ -21,14 +20,6 @@ std::unique_ptr<IOSSurface> IOSSurface::Create(std::shared_ptr<IOSContext> conte
|
||||
FML_DCHECK(layer);
|
||||
FML_DCHECK(context);
|
||||
|
||||
if ([layer.get() isKindOfClass:[CAEAGLLayer class]]) {
|
||||
return std::make_unique<IOSSurfaceGL>(
|
||||
fml::scoped_nsobject<CAEAGLLayer>(
|
||||
reinterpret_cast<CAEAGLLayer*>([layer.get() retain])), // EAGL layer
|
||||
std::move(context) // context
|
||||
);
|
||||
}
|
||||
|
||||
#if SHELL_ENABLE_METAL
|
||||
if (@available(iOS METAL_IOS_VERSION_BASELINE, *)) {
|
||||
if ([layer.get() isKindOfClass:[CAMetalLayer class]]) {
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_GL_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_GL_H_
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_gl_skia.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_render_target_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||
|
||||
@class CAEAGLLayer;
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class IOSSurfaceGL final : public IOSSurface, public GPUSurfaceGLDelegate {
|
||||
public:
|
||||
IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer, std::shared_ptr<IOSContext> context);
|
||||
|
||||
~IOSSurfaceGL() override;
|
||||
|
||||
// |IOSSurface|
|
||||
bool IsValid() const override;
|
||||
|
||||
// |IOSSurface|
|
||||
void UpdateStorageSizeIfNecessary() override;
|
||||
|
||||
// |IOSSurface|
|
||||
std::unique_ptr<Surface> CreateGPUSurface(GrDirectContext* gr_context) override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
std::unique_ptr<GLContextResult> GLContextMakeCurrent() override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
bool GLContextClearCurrent() override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
bool GLContextPresent(const GLPresentInfo& present_info) override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
intptr_t GLContextFBO(GLFrameInfo frame_info) const override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
bool AllowsDrawingWhenGpuDisabled() const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<IOSRenderTargetGL> render_target_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceGL);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_GL_H_
|
||||
@ -1,99 +0,0 @@
|
||||
// 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_skia.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<GPUSurfaceGLSkia>(sk_ref_sp(gr_context), this, true);
|
||||
} else {
|
||||
IOSContextGL* gl_context = CastToGLContext(GetContext());
|
||||
sk_sp<GrDirectContext> context = gl_context->GetMainContext();
|
||||
if (!context) {
|
||||
context = GPUSurfaceGLSkia::MakeGLContext(this);
|
||||
gl_context->SetMainContext(context);
|
||||
}
|
||||
|
||||
return std::make_unique<GPUSurfaceGLSkia>(context, this, true);
|
||||
}
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
intptr_t IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
|
||||
return IsValid() ? render_target_->GetFramebuffer() : GL_NONE;
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
SurfaceFrame::FramebufferInfo IOSSurfaceGL::GLContextFramebufferInfo() const {
|
||||
SurfaceFrame::FramebufferInfo res;
|
||||
// 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.
|
||||
res.supports_readback = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
// |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(const GLPresentInfo& present_info) {
|
||||
TRACE_EVENT0("flutter", "IOSSurfaceGL::GLContextPresent");
|
||||
return IsValid() && render_target_->PresentRenderBuffer();
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
bool IOSSurfaceGL::AllowsDrawingWhenGpuDisabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
@ -1,49 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SWITCHABLE_GL_CONTEXT_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SWITCHABLE_GL_CONTEXT_H_
|
||||
|
||||
#include "flutter/common/graphics/gl_context_switch.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/memory/thread_checker.h"
|
||||
#include "flutter/fml/memory/weak_ptr.h"
|
||||
|
||||
@class EAGLContext;
|
||||
|
||||
namespace flutter {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// The iOS implementation of a |SwitchableGLContext|.
|
||||
///
|
||||
/// It wraps a pointer to an EAGLContext. When passed in the constructor of the |GLContextSwitch|,
|
||||
/// this EAGLContext is set to current. When the |GLContextSwitch| destroys, the current context
|
||||
/// will be restored to the context before setting this EAGLContext to current.
|
||||
///
|
||||
/// Note: An |IOSSwitchableGLContext| doesn't retain the EAGLContext. Someone else must retain the
|
||||
/// pointer and outlive all the |IOSSwitchableGLContext|. This object is meant to be only owned by a
|
||||
/// |GLContextSwitch| and should be destroyed when The |GLContectSwitch| destroys.
|
||||
class IOSSwitchableGLContext final : public SwitchableGLContext {
|
||||
public:
|
||||
explicit IOSSwitchableGLContext(EAGLContext* context);
|
||||
|
||||
bool SetCurrent() override;
|
||||
|
||||
bool RemoveCurrent() override;
|
||||
|
||||
private:
|
||||
// These pointers are managed by IOSRendererTarget/IOSContextGL or a 3rd party
|
||||
// plugin that uses gl context. |IOSSwitchableGLContext| should never outlive
|
||||
// those objects. Never release this pointer within this object.
|
||||
EAGLContext* context_;
|
||||
EAGLContext* previous_context_;
|
||||
|
||||
FML_DECLARE_THREAD_CHECKER(checker);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSSwitchableGLContext);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif
|
||||
@ -1,25 +0,0 @@
|
||||
// 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_switchable_gl_context.h"
|
||||
|
||||
#import <OpenGLES/EAGL.h>
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSSwitchableGLContext::IOSSwitchableGLContext(EAGLContext* context) : context_(context){};
|
||||
|
||||
bool IOSSwitchableGLContext::SetCurrent() {
|
||||
FML_DCHECK_CREATION_THREAD_IS_CURRENT(checker);
|
||||
FML_DCHECK(context_ != nullptr);
|
||||
EAGLContext* current_context = EAGLContext.currentContext;
|
||||
previous_context_ = current_context;
|
||||
return [EAGLContext setCurrentContext:context_];
|
||||
};
|
||||
|
||||
bool IOSSwitchableGLContext::RemoveCurrent() {
|
||||
FML_DCHECK_CREATION_THREAD_IS_CURRENT(checker);
|
||||
return [EAGLContext setCurrentContext:previous_context_];
|
||||
};
|
||||
} // namespace flutter
|
||||
@ -13,7 +13,6 @@ namespace flutter {
|
||||
|
||||
enum class IOSRenderingAPI {
|
||||
kSoftware,
|
||||
kOpenGLES,
|
||||
kMetal,
|
||||
};
|
||||
|
||||
|
||||
@ -47,12 +47,14 @@ IOSRenderingAPI GetRenderingAPIForProcess(bool force_software) {
|
||||
}
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
|
||||
// OpenGL will be emulated using software rendering by Apple on the simulator, so we use the
|
||||
// Skia software rendering since it performs a little better than the emulated OpenGL.
|
||||
// When Metal isn't available we use Skia software rendering since it performs
|
||||
// a little better than emulated OpenGL. Also, omitting an OpenGL backend
|
||||
// reduces binary footprint.
|
||||
#if TARGET_OS_SIMULATOR
|
||||
return IOSRenderingAPI::kSoftware;
|
||||
#else
|
||||
return IOSRenderingAPI::kOpenGLES;
|
||||
FML_CHECK(false) << "Metal may only be unavailable on simulators";
|
||||
return IOSRenderingAPI::kSoftware;
|
||||
#endif // TARGET_OS_SIMULATOR
|
||||
}
|
||||
|
||||
@ -60,8 +62,6 @@ Class GetCoreAnimationLayerClassForRenderingAPI(IOSRenderingAPI rendering_api) {
|
||||
switch (rendering_api) {
|
||||
case IOSRenderingAPI::kSoftware:
|
||||
return [CALayer class];
|
||||
case IOSRenderingAPI::kOpenGLES:
|
||||
return [CAEAGLLayer class];
|
||||
case IOSRenderingAPI::kMetal:
|
||||
if (@available(iOS METAL_IOS_VERSION_BASELINE, *)) {
|
||||
return [CAMetalLayer class];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user