mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Reland "Introduce a delegate class for gpu metal rendering (#22611)" (flutter/engine#22777)
This reverts commit 0d71d27aa7d9058841bbba104021927c7f17b7ce.
This commit is contained in:
parent
9d46f7efef
commit
b6daee84ec
@ -673,6 +673,8 @@ FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.cc
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.h
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_metal.h
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_metal.mm
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_metal_delegate.cc
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_metal_delegate.h
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_software.h
|
||||
FILE: ../../../flutter/shell/gpu/gpu_surface_software_delegate.cc
|
||||
@ -933,6 +935,8 @@ FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStan
|
||||
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodec_Internal.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/flutter_codecs_unittest.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/flutter_standard_codec_unittest.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Flutter.podspec
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/Flutter.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h
|
||||
|
||||
@ -29,9 +29,9 @@ Animator::Animator(Delegate& delegate,
|
||||
last_vsync_start_time_(),
|
||||
last_frame_target_time_(),
|
||||
dart_frame_deadline_(0),
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
layer_tree_pipeline_(fml::MakeRefCounted<LayerTreePipeline>(2)),
|
||||
#else // FLUTTER_SHELL_ENABLE_METAL
|
||||
#else // SHELL_ENABLE_METAL
|
||||
// TODO(dnfield): We should remove this logic and set the pipeline depth
|
||||
// back to 2 in this case. See
|
||||
// https://github.com/flutter/engine/pull/9132 for discussion.
|
||||
@ -40,7 +40,7 @@ Animator::Animator(Delegate& delegate,
|
||||
task_runners.GetRasterTaskRunner()
|
||||
? 1
|
||||
: 2)),
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
pending_frame_semaphore_(1),
|
||||
frame_number_(1),
|
||||
paused_(false),
|
||||
|
||||
@ -51,6 +51,8 @@ source_set("gpu_surface_metal") {
|
||||
sources = [
|
||||
"gpu_surface_metal.h",
|
||||
"gpu_surface_metal.mm",
|
||||
"gpu_surface_metal_delegate.cc",
|
||||
"gpu_surface_metal_delegate.h",
|
||||
]
|
||||
|
||||
deps = gpu_common_deps
|
||||
|
||||
@ -5,36 +5,31 @@
|
||||
#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_
|
||||
#define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "flutter/flow/surface.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
#include "third_party/skia/include/gpu/mtl/GrMtlTypes.h"
|
||||
|
||||
@class CAMetalLayer;
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetal : public Surface {
|
||||
public:
|
||||
GPUSurfaceMetal(fml::scoped_nsobject<CAMetalLayer> layer,
|
||||
sk_sp<GrDirectContext> context,
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> command_queue);
|
||||
GPUSurfaceMetal(GPUSurfaceMetalDelegate* delegate,
|
||||
sk_sp<GrDirectContext> context);
|
||||
|
||||
// |Surface|
|
||||
~GPUSurfaceMetal();
|
||||
|
||||
private:
|
||||
fml::scoped_nsobject<CAMetalLayer> layer_;
|
||||
sk_sp<GrDirectContext> context_;
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> command_queue_;
|
||||
GrMTLHandle next_drawable_ = nullptr;
|
||||
|
||||
// |Surface|
|
||||
bool IsValid() override;
|
||||
|
||||
private:
|
||||
const GPUSurfaceMetalDelegate* delegate_;
|
||||
const MTLRenderTargetType render_target_type_;
|
||||
GrMTLHandle next_drawable_ = nullptr;
|
||||
sk_sp<GrDirectContext> context_;
|
||||
|
||||
// |Surface|
|
||||
std::unique_ptr<SurfaceFrame> AcquireFrame(const SkISize& size) override;
|
||||
|
||||
@ -47,6 +42,12 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetal : public Surface {
|
||||
// |Surface|
|
||||
std::unique_ptr<GLContextResult> MakeRenderContextCurrent() override;
|
||||
|
||||
std::unique_ptr<SurfaceFrame> AcquireFrameFromCAMetalLayer(
|
||||
const SkISize& frame_info);
|
||||
|
||||
std::unique_ptr<SurfaceFrame> AcquireFrameFromMTLTexture(
|
||||
const SkISize& frame_info);
|
||||
|
||||
void ReleaseUnusedDrawableIfNecessary();
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceMetal);
|
||||
|
||||
@ -4,9 +4,12 @@
|
||||
|
||||
#include "flutter/shell/gpu/gpu_surface_metal.h"
|
||||
|
||||
#include <QuartzCore/CAMetalLayer.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
#include "flutter/fml/platform/darwin/cf_utils.h"
|
||||
#include "flutter/fml/trace_event.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
|
||||
#include "third_party/skia/include/core/SkSurface.h"
|
||||
#include "third_party/skia/include/gpu/GrBackendSurface.h"
|
||||
#include "third_party/skia/include/ports/SkCFObject.h"
|
||||
@ -15,17 +18,10 @@ static_assert(!__has_feature(objc_arc), "ARC must be disabled.");
|
||||
|
||||
namespace flutter {
|
||||
|
||||
GPUSurfaceMetal::GPUSurfaceMetal(fml::scoped_nsobject<CAMetalLayer> layer,
|
||||
sk_sp<GrDirectContext> context,
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> command_queue)
|
||||
: layer_(std::move(layer)),
|
||||
context_(std::move(context)),
|
||||
command_queue_(std::move(command_queue)) {
|
||||
layer_.get().pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
// Flutter needs to read from the color attachment in cases where there are effects such as
|
||||
// backdrop filters.
|
||||
layer_.get().framebufferOnly = NO;
|
||||
}
|
||||
GPUSurfaceMetal::GPUSurfaceMetal(GPUSurfaceMetalDelegate* delegate, sk_sp<GrDirectContext> context)
|
||||
: delegate_(delegate),
|
||||
render_target_type_(delegate->GetRenderTargetType()),
|
||||
context_(std::move(context)) {}
|
||||
|
||||
GPUSurfaceMetal::~GPUSurfaceMetal() {
|
||||
ReleaseUnusedDrawableIfNecessary();
|
||||
@ -33,7 +29,7 @@ GPUSurfaceMetal::~GPUSurfaceMetal() {
|
||||
|
||||
// |Surface|
|
||||
bool GPUSurfaceMetal::IsValid() {
|
||||
return layer_ && context_ && command_queue_;
|
||||
return context_ != nullptr;
|
||||
}
|
||||
|
||||
// |Surface|
|
||||
@ -48,31 +44,40 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetal::AcquireFrame(const SkISize& frame
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto drawable_size = CGSizeMake(frame_size.width(), frame_size.height());
|
||||
switch (render_target_type_) {
|
||||
case MTLRenderTargetType::kCAMetalLayer:
|
||||
return AcquireFrameFromCAMetalLayer(frame_size);
|
||||
case MTLRenderTargetType::kMTLTexture:
|
||||
return AcquireFrameFromMTLTexture(frame_size);
|
||||
default:
|
||||
FML_CHECK(false) << "Unknown MTLRenderTargetType type.";
|
||||
}
|
||||
|
||||
if (!CGSizeEqualToSize(drawable_size, layer_.get().drawableSize)) {
|
||||
layer_.get().drawableSize = drawable_size;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<SurfaceFrame> GPUSurfaceMetal::AcquireFrameFromCAMetalLayer(
|
||||
const SkISize& frame_info) {
|
||||
auto layer = delegate_->GetCAMetalLayer(frame_info);
|
||||
if (!layer) {
|
||||
FML_LOG(ERROR) << "Invalid CAMetalLayer given by the embedder.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ReleaseUnusedDrawableIfNecessary();
|
||||
|
||||
// When there are platform views in the scene, the drawable needs to be presented in the same
|
||||
// transaction as the one created for platform views. When the drawable are being presented from
|
||||
// the raster thread, there is no such transaction.
|
||||
layer_.get().presentsWithTransaction = [[NSThread currentThread] isMainThread];
|
||||
|
||||
auto surface = SkSurface::MakeFromCAMetalLayer(context_.get(), // context
|
||||
layer_.get(), // layer
|
||||
kTopLeft_GrSurfaceOrigin, // origin
|
||||
1, // sample count
|
||||
kBGRA_8888_SkColorType, // color type
|
||||
nullptr, // colorspace
|
||||
nullptr, // surface properties
|
||||
&next_drawable_ // drawable (transfer out)
|
||||
);
|
||||
sk_sp<SkSurface> surface =
|
||||
SkSurface::MakeFromCAMetalLayer(context_.get(), // context
|
||||
layer, // layer
|
||||
kTopLeft_GrSurfaceOrigin, // origin
|
||||
1, // sample count
|
||||
kBGRA_8888_SkColorType, // color type
|
||||
nullptr, // colorspace
|
||||
nullptr, // surface properties
|
||||
&next_drawable_ // drawable (transfer out)
|
||||
);
|
||||
|
||||
if (!surface) {
|
||||
FML_LOG(ERROR) << "Could not create the SkSurface from the metal texture.";
|
||||
FML_LOG(ERROR) << "Could not create the SkSurface from the CAMetalLayer.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -85,23 +90,52 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetal::AcquireFrame(const SkISize& frame
|
||||
|
||||
canvas->flush();
|
||||
|
||||
if (next_drawable_ == nullptr) {
|
||||
FML_DLOG(ERROR) << "Could not acquire next Metal drawable from the SkSurface.";
|
||||
GrMTLHandle drawable = next_drawable_;
|
||||
if (!drawable) {
|
||||
FML_DLOG(ERROR) << "Unable to obtain a metal drawable.";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto command_buffer =
|
||||
fml::scoped_nsprotocol<id<MTLCommandBuffer>>([[command_queue_.get() commandBuffer] retain]);
|
||||
return delegate_->PresentDrawable(drawable);
|
||||
};
|
||||
|
||||
fml::scoped_nsprotocol<id<CAMetalDrawable>> drawable(
|
||||
reinterpret_cast<id<CAMetalDrawable>>(next_drawable_));
|
||||
next_drawable_ = nullptr;
|
||||
return std::make_unique<SurfaceFrame>(std::move(surface), true, submit_callback);
|
||||
}
|
||||
|
||||
[command_buffer.get() commit];
|
||||
[command_buffer.get() waitUntilScheduled];
|
||||
[drawable.get() present];
|
||||
std::unique_ptr<SurfaceFrame> GPUSurfaceMetal::AcquireFrameFromMTLTexture(
|
||||
const SkISize& frame_info) {
|
||||
GPUMTLTextureInfo texture = delegate_->GetMTLTexture(frame_info);
|
||||
id<MTLTexture> mtl_texture = (id<MTLTexture>)(texture.texture);
|
||||
|
||||
return true;
|
||||
if (!mtl_texture) {
|
||||
FML_LOG(ERROR) << "Invalid MTLTexture given by the embedder.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrMtlTextureInfo info;
|
||||
info.fTexture.reset([mtl_texture retain]);
|
||||
GrBackendTexture backend_texture(frame_info.width(), frame_info.height(), GrMipmapped::kNo, info);
|
||||
|
||||
sk_sp<SkSurface> surface =
|
||||
SkSurface::MakeFromBackendTexture(context_.get(), backend_texture, kTopLeft_GrSurfaceOrigin,
|
||||
1, kBGRA_8888_SkColorType, nullptr, nullptr);
|
||||
|
||||
if (!surface) {
|
||||
FML_LOG(ERROR) << "Could not create the SkSurface from the metal texture.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto submit_callback = [texture_id = texture.texture_id, delegate = delegate_](
|
||||
const SurfaceFrame& surface_frame, SkCanvas* canvas) -> bool {
|
||||
TRACE_EVENT0("flutter", "GPUSurfaceMetal::PresentTexture");
|
||||
if (canvas == nullptr) {
|
||||
FML_DLOG(ERROR) << "Canvas not available.";
|
||||
return false;
|
||||
}
|
||||
|
||||
canvas->flush();
|
||||
|
||||
return delegate->PresentTexture(texture_id);
|
||||
};
|
||||
|
||||
return std::make_unique<SurfaceFrame>(std::move(surface), true, submit_callback);
|
||||
|
||||
19
engine/src/flutter/shell/gpu/gpu_surface_metal_delegate.cc
Normal file
19
engine/src/flutter/shell/gpu/gpu_surface_metal_delegate.cc
Normal file
@ -0,0 +1,19 @@
|
||||
// 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/gpu/gpu_surface_metal_delegate.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
GPUSurfaceMetalDelegate::GPUSurfaceMetalDelegate(
|
||||
MTLRenderTargetType render_target_type)
|
||||
: render_target_type_(render_target_type) {}
|
||||
|
||||
GPUSurfaceMetalDelegate::~GPUSurfaceMetalDelegate() = default;
|
||||
|
||||
MTLRenderTargetType GPUSurfaceMetalDelegate::GetRenderTargetType() {
|
||||
return render_target_type_;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
100
engine/src/flutter/shell/gpu/gpu_surface_metal_delegate.h
Normal file
100
engine/src/flutter/shell/gpu/gpu_surface_metal_delegate.h
Normal file
@ -0,0 +1,100 @@
|
||||
// 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_GPU_GPU_SURFACE_METAL_DELEGATE_H_
|
||||
#define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_DELEGATE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "third_party/skia/include/core/SkSize.h"
|
||||
#include "third_party/skia/include/core/SkSurface.h"
|
||||
#include "third_party/skia/include/gpu/mtl/GrMtlTypes.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
// expected to be id<MTLDevice>
|
||||
typedef void* GPUMTLDeviceHandle;
|
||||
|
||||
// expected to be id<MTLCommandQueues>
|
||||
typedef void* GPUMTLCommandQueueHandle;
|
||||
|
||||
// expected to be CAMetalLayer*
|
||||
typedef void* GPUCAMetalLayerHandle;
|
||||
|
||||
// expected to be id<MTLTexture>
|
||||
typedef void* GPUMTLTextureHandle;
|
||||
|
||||
struct GPUMTLTextureInfo {
|
||||
intptr_t texture_id;
|
||||
GPUMTLTextureHandle texture;
|
||||
};
|
||||
|
||||
enum class MTLRenderTargetType { kMTLTexture, kCAMetalLayer };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Interface implemented by all platform surfaces that can present
|
||||
/// a metal backing store to the "screen". The GPU surface
|
||||
/// abstraction (which abstracts the client rendering API) uses this
|
||||
/// delegation pattern to tell the platform surface (which abstracts
|
||||
/// how backing stores fulfilled by the selected client rendering
|
||||
/// API end up on the "screen" on a particular platform) when the
|
||||
/// rasterizer needs to allocate and present the software backing
|
||||
/// store.
|
||||
///
|
||||
/// @see |IOSurfaceMetal| and |EmbedderSurfaceMetal|.
|
||||
///
|
||||
class GPUSurfaceMetalDelegate {
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Construct a new GPUSurfaceMetalDelegate object with the specified
|
||||
/// render_target type.
|
||||
///
|
||||
/// @see |MTLRenderTargetType|
|
||||
///
|
||||
explicit GPUSurfaceMetalDelegate(MTLRenderTargetType render_target);
|
||||
|
||||
virtual ~GPUSurfaceMetalDelegate();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Returns the handle to the CAMetalLayer to render to. This is only
|
||||
/// called when the specifed render target type is `kCAMetalLayer`.
|
||||
///
|
||||
virtual GPUCAMetalLayerHandle GetCAMetalLayer(
|
||||
const SkISize& frame_info) const = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Presents the drawable to the "screen". The drawable is obtained
|
||||
/// from the CAMetalLayer that given by `GetCAMetalLayer` call. This is only
|
||||
/// called when the specified render target type in `kCAMetalLayer`.
|
||||
///
|
||||
/// @see |GPUSurfaceMetalDelegate::GetCAMetalLayer|
|
||||
///
|
||||
virtual bool PresentDrawable(GrMTLHandle drawable) const = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Returns the handle to the MTLTexture to render to. This is only
|
||||
/// called when the specefied render target type is `kMTLTexture`.
|
||||
///
|
||||
virtual GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Presents the texture with `texture_id` to the "screen".
|
||||
/// `texture_id` corresponds to a texture that has been obtained by an earlier
|
||||
/// call to `GetMTLTexture`. This is only called when the specefied render
|
||||
/// target type is `kMTLTexture`.
|
||||
///
|
||||
/// @see |GPUSurfaceMetalDelegate::GetMTLTexture|
|
||||
///
|
||||
virtual bool PresentTexture(intptr_t texture_id) const = 0;
|
||||
|
||||
MTLRenderTargetType GetRenderTargetType();
|
||||
|
||||
private:
|
||||
const MTLRenderTargetType render_target_type_;
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_DELEGATE_H_
|
||||
26
engine/src/flutter/shell/platform/darwin/graphics/BUILD.gn
Normal file
26
engine/src/flutter/shell/platform/darwin/graphics/BUILD.gn
Normal file
@ -0,0 +1,26 @@
|
||||
# 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.
|
||||
|
||||
assert(is_ios || is_mac)
|
||||
|
||||
import("//flutter/common/config.gni")
|
||||
|
||||
source_set("graphics") {
|
||||
cflags_objc = flutter_cflags_objc
|
||||
cflags_objcc = flutter_cflags_objcc
|
||||
|
||||
sources = [
|
||||
"FlutterDarwinContextMetal.h",
|
||||
"FlutterDarwinContextMetal.mm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//flutter/common/graphics",
|
||||
"//flutter/fml",
|
||||
]
|
||||
|
||||
public_deps = [ "//third_party/skia" ]
|
||||
|
||||
public_configs = [ "//flutter:config" ]
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
// 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 SHELL_PLATFORM_DARWIN_GRAPHICS_DARWIN_CONTEXT_METAL_H_
|
||||
#define SHELL_PLATFORM_DARWIN_GRAPHICS_DARWIN_CONTEXT_METAL_H_
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Provides skia GrContexts that are shared between iOS and macOS embeddings.
|
||||
*/
|
||||
@interface FlutterDarwinContextMetal : NSObject
|
||||
|
||||
/**
|
||||
* Initializes a FlutterDarwinContextMetal with the system default MTLDevice and a new
|
||||
* MTLCommandQueue.
|
||||
*/
|
||||
- (instancetype)initWithDefaultMTLDevice;
|
||||
|
||||
/**
|
||||
* Initializes a FlutterDarwinContextMetal with provided MTLDevice and MTLCommandQueue.
|
||||
*/
|
||||
- (instancetype)initWithMTLDevice:(id<MTLDevice>)mtlDevice
|
||||
commandQueue:(id<MTLCommandQueue>)commandQueue;
|
||||
|
||||
/**
|
||||
* MTLDevice that is backing this context.s
|
||||
*/
|
||||
@property(nonatomic, readonly) id<MTLDevice> mtlDevice;
|
||||
|
||||
/**
|
||||
* MTLCommandQueue that is acquired from the `mtlDevice`. This queue is used both for rendering and
|
||||
* resource related commands.
|
||||
*/
|
||||
@property(nonatomic, readonly) id<MTLCommandQueue> mtlCommandQueue;
|
||||
|
||||
/**
|
||||
* Skia GrContext that is used for rendering.
|
||||
*/
|
||||
@property(nonatomic, readonly) sk_sp<GrDirectContext> mainContext;
|
||||
|
||||
/**
|
||||
* Skia GrContext that is used for resources (uploading textures etc).
|
||||
*/
|
||||
@property(nonatomic, readonly) sk_sp<GrDirectContext> resourceContext;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // SHELL_PLATFORM_DARWIN_GRAPHICS_DARWIN_CONTEXT_METAL_H_
|
||||
@ -0,0 +1,70 @@
|
||||
// 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/graphics/FlutterDarwinContextMetal.h"
|
||||
|
||||
#include "flutter/common/graphics/persistent_cache.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "third_party/skia/include/gpu/GrContextOptions.h"
|
||||
|
||||
static GrContextOptions CreateMetalGrContextOptions() {
|
||||
GrContextOptions options = {};
|
||||
if (flutter::PersistentCache::cache_sksl()) {
|
||||
options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL;
|
||||
}
|
||||
flutter::PersistentCache::MarkStrategySet();
|
||||
options.fPersistentCache = flutter::PersistentCache::GetCacheForProcess();
|
||||
return options;
|
||||
}
|
||||
|
||||
@implementation FlutterDarwinContextMetal
|
||||
|
||||
- (instancetype)initWithDefaultMTLDevice {
|
||||
id<MTLDevice> mtlDevice = MTLCreateSystemDefaultDevice();
|
||||
return [self initWithMTLDevice:mtlDevice commandQueue:[mtlDevice newCommandQueue]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithMTLDevice:(id<MTLDevice>)mtlDevice
|
||||
commandQueue:(id<MTLCommandQueue>)commandQueue {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_mtlDevice = mtlDevice;
|
||||
|
||||
if (!_mtlDevice) {
|
||||
FML_DLOG(ERROR) << "Could not acquire Metal device.";
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
_mtlCommandQueue = commandQueue;
|
||||
|
||||
if (!_mtlCommandQueue) {
|
||||
FML_DLOG(ERROR) << "Could not create Metal command queue.";
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
[_mtlCommandQueue setLabel:@"Flutter Main Queue"];
|
||||
|
||||
auto contextOptions = CreateMetalGrContextOptions();
|
||||
|
||||
// Skia expect arguments to `MakeMetal` transfer ownership of the reference in for release later
|
||||
// when the GrDirectContext is collected.
|
||||
_mainContext =
|
||||
GrDirectContext::MakeMetal([_mtlDevice retain], [_mtlCommandQueue retain], contextOptions);
|
||||
_resourceContext =
|
||||
GrDirectContext::MakeMetal([_mtlDevice retain], [_mtlCommandQueue retain], contextOptions);
|
||||
|
||||
if (!_mainContext || !_resourceContext) {
|
||||
FML_DLOG(ERROR) << "Could not create Skia Metal contexts.";
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
_resourceContext->setResourceCacheLimits(0u, 0u);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -42,6 +42,8 @@ source_set("flutter_framework_source") {
|
||||
cflags_objc = flutter_cflags_objc
|
||||
cflags_objcc = flutter_cflags_objcc
|
||||
|
||||
deps = []
|
||||
|
||||
sources = [
|
||||
"framework/Source/FlutterAppDelegate.mm",
|
||||
"framework/Source/FlutterBinaryMessengerRelay.mm",
|
||||
@ -116,8 +118,6 @@ source_set("flutter_framework_source") {
|
||||
defines = [ "FLUTTER_FRAMEWORK=1" ]
|
||||
|
||||
if (shell_enable_metal) {
|
||||
defines += [ "FLUTTER_SHELL_ENABLE_METAL=1" ]
|
||||
|
||||
sources += [
|
||||
"ios_context_metal.h",
|
||||
"ios_context_metal.mm",
|
||||
@ -126,9 +126,11 @@ source_set("flutter_framework_source") {
|
||||
"ios_surface_metal.h",
|
||||
"ios_surface_metal.mm",
|
||||
]
|
||||
|
||||
deps += [ "//flutter/shell/platform/darwin/graphics" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
deps += [
|
||||
":ios_gpu_configuration",
|
||||
"//flutter/common",
|
||||
"//flutter/common/graphics",
|
||||
@ -144,7 +146,10 @@ source_set("flutter_framework_source") {
|
||||
"//third_party/skia",
|
||||
]
|
||||
|
||||
public_configs = [ "//flutter:config" ]
|
||||
public_configs = [
|
||||
":ios_gpu_configuration_config",
|
||||
"//flutter:config",
|
||||
]
|
||||
|
||||
libs = [
|
||||
"AudioToolbox.framework",
|
||||
@ -219,6 +224,7 @@ shared_library("ios_test_flutter") {
|
||||
]
|
||||
deps = [
|
||||
":flutter_framework_source",
|
||||
":ios_gpu_configuration",
|
||||
":ios_test_flutter_mrc",
|
||||
"//flutter/common:common",
|
||||
"//flutter/shell/platform/darwin/common:framework_shared",
|
||||
@ -228,7 +234,10 @@ shared_library("ios_test_flutter") {
|
||||
"//third_party/rapidjson",
|
||||
"//third_party/skia",
|
||||
]
|
||||
public_configs = [ "//flutter:config" ]
|
||||
public_configs = [
|
||||
":ios_gpu_configuration_config",
|
||||
"//flutter:config",
|
||||
]
|
||||
}
|
||||
|
||||
shared_library("create_flutter_framework_dylib") {
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_gl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_software.h"
|
||||
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_metal.h"
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
|
||||
namespace flutter {
|
||||
|
||||
@ -24,10 +24,10 @@ std::unique_ptr<IOSContext> IOSContext::Create(IOSRenderingAPI rendering_api) {
|
||||
return std::make_unique<IOSContextGL>();
|
||||
case IOSRenderingAPI::kSoftware:
|
||||
return std::make_unique<IOSContextSoftware>();
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
case IOSRenderingAPI::kMetal:
|
||||
return std::make_unique<IOSContextMetal>();
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/platform/darwin/cf_utils.h"
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context.h"
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
|
||||
@ -21,21 +22,15 @@ class IOSContextMetal final : public IOSContext {
|
||||
|
||||
~IOSContextMetal();
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLDevice>> GetDevice() const;
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> GetMainCommandQueue() const;
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> GetResourceCommandQueue() const;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> GetDarwinContext() const;
|
||||
|
||||
sk_sp<GrDirectContext> GetMainContext() const;
|
||||
|
||||
sk_sp<GrDirectContext> GetResourceContext() const;
|
||||
|
||||
private:
|
||||
fml::scoped_nsprotocol<id<MTLDevice>> device_;
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> main_queue_;
|
||||
sk_sp<GrDirectContext> main_context_;
|
||||
sk_sp<GrDirectContext> resource_context_;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> darwin_context_metal_;
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> main_command_queue_;
|
||||
fml::CFRef<CVMetalTextureCacheRef> texture_cache_;
|
||||
|
||||
// |IOSContext|
|
||||
|
||||
@ -6,58 +6,27 @@
|
||||
|
||||
#include "flutter/common/graphics/persistent_cache.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h"
|
||||
#include "third_party/skia/include/gpu/GrContextOptions.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
static GrContextOptions CreateMetalGrContextOptions() {
|
||||
GrContextOptions options = {};
|
||||
if (PersistentCache::cache_sksl()) {
|
||||
options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL;
|
||||
}
|
||||
PersistentCache::MarkStrategySet();
|
||||
options.fPersistentCache = PersistentCache::GetCacheForProcess();
|
||||
return options;
|
||||
}
|
||||
|
||||
IOSContextMetal::IOSContextMetal() {
|
||||
device_.reset([MTLCreateSystemDefaultDevice() retain]);
|
||||
if (!device_) {
|
||||
FML_DLOG(ERROR) << "Could not acquire Metal device.";
|
||||
darwin_context_metal_ = fml::scoped_nsobject<FlutterDarwinContextMetal>{
|
||||
[[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice] retain]};
|
||||
|
||||
if (!darwin_context_metal_) {
|
||||
return;
|
||||
}
|
||||
|
||||
main_queue_.reset([device_ newCommandQueue]);
|
||||
|
||||
if (!main_queue_) {
|
||||
FML_DLOG(ERROR) << "Could not create Metal command queue.";
|
||||
return;
|
||||
}
|
||||
|
||||
[main_queue_ setLabel:@"Flutter Main Queue"];
|
||||
|
||||
const auto& context_options = CreateMetalGrContextOptions();
|
||||
|
||||
// Skia expect arguments to `MakeMetal` transfer ownership of the reference in for release later
|
||||
// when the GrDirectContext is collected.
|
||||
main_context_ =
|
||||
GrDirectContext::MakeMetal([device_ retain], [main_queue_ retain], context_options);
|
||||
resource_context_ =
|
||||
GrDirectContext::MakeMetal([device_ retain], [main_queue_ retain], context_options);
|
||||
|
||||
if (!main_context_ || !resource_context_) {
|
||||
FML_DLOG(ERROR) << "Could not create Skia Metal contexts.";
|
||||
return;
|
||||
}
|
||||
|
||||
resource_context_->setResourceCacheLimits(0u, 0u);
|
||||
main_command_queue_.reset([darwin_context_metal_.get().mtlCommandQueue retain]);
|
||||
|
||||
CVMetalTextureCacheRef texture_cache_raw = NULL;
|
||||
auto cv_return = CVMetalTextureCacheCreate(kCFAllocatorDefault, // allocator
|
||||
NULL, // cache attributes (NULL default)
|
||||
device_.get(), // metal device
|
||||
NULL, // texture attributes (NULL default)
|
||||
NULL, // cache attributes (NULL default)
|
||||
darwin_context_metal_.get().mtlDevice, // metal device
|
||||
NULL, // texture attributes (NULL default)
|
||||
&texture_cache_raw // [out] cache
|
||||
);
|
||||
if (cv_return != kCVReturnSuccess) {
|
||||
@ -69,30 +38,21 @@ IOSContextMetal::IOSContextMetal() {
|
||||
|
||||
IOSContextMetal::~IOSContextMetal() = default;
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLDevice>> IOSContextMetal::GetDevice() const {
|
||||
return device_;
|
||||
}
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> IOSContextMetal::GetMainCommandQueue() const {
|
||||
return main_queue_;
|
||||
}
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLCommandQueue>> IOSContextMetal::GetResourceCommandQueue() const {
|
||||
// TODO(52150): Create a dedicated resource queue once multiple queues are supported in Skia.
|
||||
return main_queue_;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> IOSContextMetal::GetDarwinContext() const {
|
||||
return darwin_context_metal_;
|
||||
}
|
||||
|
||||
sk_sp<GrDirectContext> IOSContextMetal::GetMainContext() const {
|
||||
return main_context_;
|
||||
return darwin_context_metal_.get().mainContext;
|
||||
}
|
||||
|
||||
sk_sp<GrDirectContext> IOSContextMetal::GetResourceContext() const {
|
||||
return resource_context_;
|
||||
return darwin_context_metal_.get().resourceContext;
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> IOSContextMetal::CreateResourceContext() {
|
||||
return resource_context_;
|
||||
return darwin_context_metal_.get().resourceContext;
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
|
||||
#include "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
|
||||
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_metal.h"
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
|
||||
namespace flutter {
|
||||
|
||||
@ -28,7 +28,7 @@ std::unique_ptr<IOSSurface> IOSSurface::Create(std::shared_ptr<IOSContext> conte
|
||||
);
|
||||
}
|
||||
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
if (@available(iOS METAL_IOS_VERSION_BASELINE, *)) {
|
||||
if ([layer.get() isKindOfClass:[CAMetalLayer class]]) {
|
||||
return std::make_unique<IOSSurfaceMetal>(
|
||||
@ -38,7 +38,7 @@ std::unique_ptr<IOSSurface> IOSSurface::Create(std::shared_ptr<IOSContext> conte
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
|
||||
return std::make_unique<IOSSurfaceSoftware>(std::move(layer), // layer
|
||||
std::move(context) // context
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_METAL_H_
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||
#include "third_party/skia/include/gpu/mtl/GrMtlTypes.h"
|
||||
|
||||
@ -13,7 +14,8 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetal final : public IOSSurface {
|
||||
class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetal final : public IOSSurface,
|
||||
public GPUSurfaceMetalDelegate {
|
||||
public:
|
||||
IOSSurfaceMetal(fml::scoped_nsobject<CAMetalLayer> layer, std::shared_ptr<IOSContext> context);
|
||||
|
||||
@ -22,6 +24,8 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetal final : public IOSSurface
|
||||
|
||||
private:
|
||||
fml::scoped_nsobject<CAMetalLayer> layer_;
|
||||
id<MTLDevice> device_;
|
||||
id<MTLCommandQueue> command_queue_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
// |IOSSurface|
|
||||
@ -33,6 +37,18 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetal final : public IOSSurface
|
||||
// |IOSSurface|
|
||||
std::unique_ptr<Surface> CreateGPUSurface(GrDirectContext* gr_context) override;
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override;
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
bool PresentDrawable(GrMTLHandle drawable) const override;
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const override;
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
bool PresentTexture(intptr_t texture_id) const override;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceMetal);
|
||||
};
|
||||
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface_metal.h"
|
||||
|
||||
#include "flutter/shell/gpu/gpu_surface_metal.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_metal.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
|
||||
#include "flutter/shell/platform/darwin/ios/ios_context_metal.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
@ -15,17 +16,14 @@ static IOSContextMetal* CastToMetalContext(const std::shared_ptr<IOSContext>& co
|
||||
|
||||
IOSSurfaceMetal::IOSSurfaceMetal(fml::scoped_nsobject<CAMetalLayer> layer,
|
||||
std::shared_ptr<IOSContext> context)
|
||||
: IOSSurface(std::move(context)), layer_(std::move(layer)) {
|
||||
if (!layer_) {
|
||||
return;
|
||||
}
|
||||
|
||||
: IOSSurface(std::move(context)),
|
||||
GPUSurfaceMetalDelegate(MTLRenderTargetType::kCAMetalLayer),
|
||||
layer_(std::move(layer)) {
|
||||
is_valid_ = layer_;
|
||||
auto metal_context = CastToMetalContext(GetContext());
|
||||
|
||||
layer_.get().device = metal_context->GetDevice().get();
|
||||
layer_.get().presentsWithTransaction = YES;
|
||||
|
||||
is_valid_ = true;
|
||||
auto darwin_context = metal_context->GetDarwinContext().get();
|
||||
command_queue_ = darwin_context.mtlCommandQueue;
|
||||
device_ = darwin_context.mtlDevice;
|
||||
}
|
||||
|
||||
// |IOSSurface|
|
||||
@ -44,11 +42,60 @@ void IOSSurfaceMetal::UpdateStorageSizeIfNecessary() {
|
||||
// |IOSSurface|
|
||||
std::unique_ptr<Surface> IOSSurfaceMetal::CreateGPUSurface(GrDirectContext* /* unused */) {
|
||||
auto metal_context = CastToMetalContext(GetContext());
|
||||
|
||||
return std::make_unique<GPUSurfaceMetal>(layer_, // layer
|
||||
metal_context->GetMainContext(), // context
|
||||
metal_context->GetMainCommandQueue() // command queue
|
||||
return std::make_unique<GPUSurfaceMetal>(this, // layer
|
||||
metal_context->GetMainContext() // context
|
||||
);
|
||||
}
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
GPUCAMetalLayerHandle IOSSurfaceMetal::GetCAMetalLayer(const SkISize& frame_info) const {
|
||||
CAMetalLayer* layer = layer_.get();
|
||||
layer.device = device_;
|
||||
|
||||
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
// Flutter needs to read from the color attachment in cases where there are effects such as
|
||||
// backdrop filters.
|
||||
layer.framebufferOnly = NO;
|
||||
|
||||
const auto drawable_size = CGSizeMake(frame_info.width(), frame_info.height());
|
||||
if (!CGSizeEqualToSize(drawable_size, layer.drawableSize)) {
|
||||
layer.drawableSize = drawable_size;
|
||||
}
|
||||
|
||||
// When there are platform views in the scene, the drawable needs to be presented in the same
|
||||
// transaction as the one created for platform views. When the drawable are being presented from
|
||||
// the raster thread, there is no such transaction.
|
||||
layer.presentsWithTransaction = [[NSThread currentThread] isMainThread];
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
bool IOSSurfaceMetal::PresentDrawable(GrMTLHandle drawable) const {
|
||||
if (drawable == nullptr) {
|
||||
FML_DLOG(ERROR) << "Could not acquire next Metal drawable from the SkSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto command_buffer =
|
||||
fml::scoped_nsprotocol<id<MTLCommandBuffer>>([[command_queue_ commandBuffer] retain]);
|
||||
[command_buffer.get() commit];
|
||||
[command_buffer.get() waitUntilScheduled];
|
||||
|
||||
[reinterpret_cast<id<CAMetalDrawable>>(drawable) present];
|
||||
return true;
|
||||
}
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
GPUMTLTextureInfo IOSSurfaceMetal::GetMTLTexture(const SkISize& frame_info) const {
|
||||
FML_CHECK(false) << "render to texture not supported on ios";
|
||||
return {.texture_id = -1, .texture = nullptr};
|
||||
}
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
bool IOSSurfaceMetal::PresentTexture(intptr_t texture_id) const {
|
||||
FML_CHECK(false) << "render to texture not supported on ios";
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -6,17 +6,17 @@
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <QuartzCore/CAEAGLLayer.h>
|
||||
#include <QuartzCore/CAMetalLayer.h>
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
#if SHELL_ENABLE_METAL
|
||||
#include <Metal/Metal.h>
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
bool ShouldUseMetalRenderer() {
|
||||
bool ios_version_supports_metal = false;
|
||||
if (@available(iOS METAL_IOS_VERSION_BASELINE, *)) {
|
||||
@ -25,7 +25,7 @@ bool ShouldUseMetalRenderer() {
|
||||
}
|
||||
return ios_version_supports_metal;
|
||||
}
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#endif // SHELL_ENABLE_METAL
|
||||
|
||||
IOSRenderingAPI GetRenderingAPIForProcess(bool force_software) {
|
||||
#if TARGET_OS_SIMULATOR
|
||||
@ -39,12 +39,12 @@ IOSRenderingAPI GetRenderingAPIForProcess(bool force_software) {
|
||||
}
|
||||
#endif // TARGET_OS_SIMULATOR
|
||||
|
||||
#if FLUTTER_SHELL_ENABLE_METAL
|
||||
#if SHELL_ENABLE_METAL
|
||||
static bool should_use_metal = ShouldUseMetalRenderer();
|
||||
if (should_use_metal) {
|
||||
return IOSRenderingAPI::kMetal;
|
||||
}
|
||||
#endif // FLUTTER_SHELL_ENABLE_METAL
|
||||
#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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user