[Impeller] Support external textures on iOS (flutter/engine#36498)
This commit is contained in:
@@ -2407,8 +2407,10 @@ 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/graphics/FlutterDarwinContextMetalImpeller.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h
|
||||
FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm
|
||||
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/Flutter.h
|
||||
|
||||
@@ -21,6 +21,7 @@ source_set("graphics") {
|
||||
# additions here could result in added app sizes across embeddings.
|
||||
deps = [
|
||||
"//flutter/assets",
|
||||
"//flutter/display_list",
|
||||
"//flutter/fml",
|
||||
"//flutter/shell/version:version",
|
||||
"//third_party/boringssl",
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "flutter/display_list/display_list_builder.h"
|
||||
#include "flutter/display_list/display_list_paint.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/synchronization/waitable_event.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
@@ -33,16 +35,22 @@ class ContextListener {
|
||||
|
||||
class Texture : public ContextListener {
|
||||
public:
|
||||
struct PaintContext {
|
||||
SkCanvas* canvas = nullptr;
|
||||
DisplayListBuilder* builder = nullptr;
|
||||
GrDirectContext* gr_context = nullptr;
|
||||
const SkPaint* sk_paint = nullptr;
|
||||
const DlPaint* dl_paint = nullptr;
|
||||
};
|
||||
|
||||
explicit Texture(int64_t id); // Called from UI or raster thread.
|
||||
virtual ~Texture(); // Called from raster thread.
|
||||
|
||||
// Called from raster thread.
|
||||
virtual void Paint(SkCanvas& canvas,
|
||||
virtual void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint = nullptr) = 0;
|
||||
const SkSamplingOptions& sampling) = 0;
|
||||
|
||||
// Called on raster thread.
|
||||
virtual void MarkNewFrameAvailable() = 0;
|
||||
|
||||
@@ -62,8 +62,14 @@ void TextureLayer::Paint(PaintContext& context) const {
|
||||
return;
|
||||
}
|
||||
AutoCachePaint cache_paint(context);
|
||||
texture->Paint(*context.leaf_nodes_canvas, paint_bounds(), freeze_,
|
||||
context.gr_context, ToSk(sampling_), cache_paint.sk_paint());
|
||||
Texture::PaintContext ctx{
|
||||
.canvas = context.leaf_nodes_canvas,
|
||||
.builder = context.leaf_nodes_builder,
|
||||
.gr_context = context.gr_context,
|
||||
.sk_paint = cache_paint.sk_paint(),
|
||||
.dl_paint = cache_paint.dl_paint(),
|
||||
};
|
||||
texture->Paint(ctx, paint_bounds(), freeze_, ToSk(sampling_));
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/flow/testing/mock_texture.h"
|
||||
#include "flutter/flow/layers/layer.h"
|
||||
#include "flutter/flow/testing/skia_gpu_object_layer_test.h"
|
||||
|
||||
namespace flutter {
|
||||
@@ -10,14 +11,13 @@ namespace testing {
|
||||
|
||||
MockTexture::MockTexture(int64_t textureId) : Texture(textureId) {}
|
||||
|
||||
void MockTexture::Paint(SkCanvas& canvas,
|
||||
void MockTexture::Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) {
|
||||
paint_calls_.emplace_back(
|
||||
PaintCall{canvas, bounds, freeze, context, sampling, paint});
|
||||
const SkSamplingOptions& sampling) {
|
||||
paint_calls_.emplace_back(PaintCall{*(context.canvas), bounds, freeze,
|
||||
context.gr_context, sampling,
|
||||
context.sk_paint});
|
||||
}
|
||||
|
||||
bool operator==(const MockTexture::PaintCall& a,
|
||||
|
||||
@@ -28,12 +28,10 @@ class MockTexture : public Texture {
|
||||
explicit MockTexture(int64_t textureId);
|
||||
|
||||
// Called from raster thread.
|
||||
void Paint(SkCanvas& canvas,
|
||||
void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint = nullptr) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
void OnGrContextCreated() override { gr_context_created_ = true; }
|
||||
void OnGrContextDestroyed() override { gr_context_destroyed_ = true; }
|
||||
|
||||
@@ -34,9 +34,11 @@ TEST(MockTextureTest, PaintCalls) {
|
||||
MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr, sampling},
|
||||
MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr, sampling}};
|
||||
auto texture = std::make_shared<MockTexture>(0);
|
||||
|
||||
texture->Paint(canvas, paint_bounds1, false, nullptr, sampling);
|
||||
texture->Paint(canvas, paint_bounds2, true, nullptr, sampling);
|
||||
Texture::PaintContext context{
|
||||
.canvas = &canvas,
|
||||
};
|
||||
texture->Paint(context, paint_bounds1, false, sampling);
|
||||
texture->Paint(context, paint_bounds2, true, sampling);
|
||||
EXPECT_EQ(texture->paint_calls(), expected_paint_calls);
|
||||
}
|
||||
|
||||
@@ -49,9 +51,11 @@ TEST(MockTextureTest, PaintCallsWithLinearSampling) {
|
||||
MockTexture::PaintCall{canvas, paint_bounds1, false, nullptr, sampling},
|
||||
MockTexture::PaintCall{canvas, paint_bounds2, true, nullptr, sampling}};
|
||||
auto texture = std::make_shared<MockTexture>(0);
|
||||
|
||||
texture->Paint(canvas, paint_bounds1, false, nullptr, sampling);
|
||||
texture->Paint(canvas, paint_bounds2, true, nullptr, sampling);
|
||||
Texture::PaintContext context{
|
||||
.canvas = &canvas,
|
||||
};
|
||||
texture->Paint(context, paint_bounds1, false, sampling);
|
||||
texture->Paint(context, paint_bounds2, true, sampling);
|
||||
EXPECT_EQ(texture->paint_calls(), expected_paint_calls);
|
||||
}
|
||||
|
||||
|
||||
@@ -1071,7 +1071,7 @@ void DisplayListDispatcher::drawImageRect(
|
||||
std::make_shared<Image>(image->impeller_texture()), // image
|
||||
ToRect(src), // source rect
|
||||
ToRect(dst), // destination rect
|
||||
paint_, // paint
|
||||
render_with_attributes ? paint_ : Paint(), // paint
|
||||
ToSamplerDescriptor(sampling) // sampling
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace impeller {
|
||||
class ContextMTL final : public Context,
|
||||
public BackendCast<ContextMTL, Context> {
|
||||
public:
|
||||
static std::shared_ptr<Context> Create(
|
||||
static std::shared_ptr<ContextMTL> Create(
|
||||
const std::vector<std::string>& shader_library_paths);
|
||||
|
||||
static std::shared_ptr<Context> Create(
|
||||
static std::shared_ptr<ContextMTL> Create(
|
||||
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
|
||||
const std::string& label);
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ static id<MTLDevice> CreateMetalDevice() {
|
||||
return ::MTLCreateSystemDefaultDevice();
|
||||
}
|
||||
|
||||
std::shared_ptr<Context> ContextMTL::Create(
|
||||
std::shared_ptr<ContextMTL> ContextMTL::Create(
|
||||
const std::vector<std::string>& shader_library_paths) {
|
||||
auto device = CreateMetalDevice();
|
||||
auto context = std::shared_ptr<ContextMTL>(new ContextMTL(
|
||||
@@ -164,7 +164,7 @@ std::shared_ptr<Context> ContextMTL::Create(
|
||||
return context;
|
||||
}
|
||||
|
||||
std::shared_ptr<Context> ContextMTL::Create(
|
||||
std::shared_ptr<ContextMTL> ContextMTL::Create(
|
||||
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
|
||||
const std::string& label) {
|
||||
auto device = CreateMetalDevice();
|
||||
|
||||
@@ -15,16 +15,24 @@ namespace impeller {
|
||||
class TextureMTL final : public Texture,
|
||||
public BackendCast<TextureMTL, Texture> {
|
||||
public:
|
||||
TextureMTL(TextureDescriptor desc, id<MTLTexture> texture);
|
||||
TextureMTL(TextureDescriptor desc,
|
||||
id<MTLTexture> texture,
|
||||
bool wrapped = false);
|
||||
|
||||
static std::shared_ptr<TextureMTL> Wrapper(TextureDescriptor desc,
|
||||
id<MTLTexture> texture);
|
||||
|
||||
// |Texture|
|
||||
~TextureMTL() override;
|
||||
|
||||
id<MTLTexture> GetMTLTexture() const;
|
||||
|
||||
bool IsWrapped() const;
|
||||
|
||||
private:
|
||||
id<MTLTexture> texture_ = nullptr;
|
||||
bool is_valid_ = false;
|
||||
bool is_wrapped_ = false;
|
||||
|
||||
// |Texture|
|
||||
void SetLabel(std::string_view label) override;
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
#include "impeller/renderer/backend/metal/texture_mtl.h"
|
||||
|
||||
#include "impeller/base/validation.h"
|
||||
#include "impeller/renderer/texture_descriptor.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
TextureMTL::TextureMTL(TextureDescriptor p_desc, id<MTLTexture> texture)
|
||||
TextureMTL::TextureMTL(TextureDescriptor p_desc,
|
||||
id<MTLTexture> texture,
|
||||
bool wrapped)
|
||||
: Texture(p_desc), texture_(texture) {
|
||||
const auto& desc = GetTextureDescriptor();
|
||||
|
||||
@@ -21,9 +24,15 @@ TextureMTL::TextureMTL(TextureDescriptor p_desc, id<MTLTexture> texture)
|
||||
return;
|
||||
}
|
||||
|
||||
is_wrapped_ = wrapped;
|
||||
is_valid_ = true;
|
||||
}
|
||||
|
||||
std::shared_ptr<TextureMTL> TextureMTL::Wrapper(TextureDescriptor desc,
|
||||
id<MTLTexture> texture) {
|
||||
return std::make_shared<TextureMTL>(desc, texture, true);
|
||||
}
|
||||
|
||||
TextureMTL::~TextureMTL() = default;
|
||||
|
||||
void TextureMTL::SetLabel(std::string_view label) {
|
||||
@@ -42,7 +51,7 @@ bool TextureMTL::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
|
||||
bool TextureMTL::OnSetContents(const uint8_t* contents,
|
||||
size_t length,
|
||||
size_t slice) {
|
||||
if (!IsValid() || !contents) {
|
||||
if (!IsValid() || !contents || is_wrapped_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,4 +92,8 @@ bool TextureMTL::IsValid() const {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
bool TextureMTL::IsWrapped() const {
|
||||
return is_wrapped_;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@@ -61,6 +61,10 @@ bool Texture::IsSliceValid(size_t slice) const {
|
||||
FML_UNREACHABLE();
|
||||
}
|
||||
|
||||
void Texture::SetIntent(TextureIntent intent) {
|
||||
intent_ = intent;
|
||||
}
|
||||
|
||||
TextureIntent Texture::GetIntent() const {
|
||||
return intent_;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ class Texture {
|
||||
|
||||
const TextureDescriptor& GetTextureDescriptor() const;
|
||||
|
||||
void SetIntent(TextureIntent intent);
|
||||
|
||||
TextureIntent GetIntent() const;
|
||||
|
||||
virtual Scalar GetYCoordScale() const;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_skia.h"
|
||||
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
@@ -30,12 +30,12 @@ static fml::scoped_nsprotocol<id<MTLTexture>> CreateOffscreenTexture(id<MTLDevic
|
||||
class DarwinContextMetal {
|
||||
public:
|
||||
DarwinContextMetal()
|
||||
: context_([[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice]),
|
||||
: context_([[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]),
|
||||
offscreen_texture_(CreateOffscreenTexture([context_.get() device])) {}
|
||||
|
||||
~DarwinContextMetal() = default;
|
||||
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> context() const { return context_; }
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalSkia> context() const { return context_; }
|
||||
|
||||
fml::scoped_nsprotocol<id<MTLTexture>> offscreen_texture() const { return offscreen_texture_; }
|
||||
|
||||
@@ -47,7 +47,7 @@ class DarwinContextMetal {
|
||||
}
|
||||
|
||||
private:
|
||||
const fml::scoped_nsobject<FlutterDarwinContextMetal> context_;
|
||||
const fml::scoped_nsobject<FlutterDarwinContextMetalSkia> context_;
|
||||
const fml::scoped_nsprotocol<id<MTLTexture>> offscreen_texture_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(DarwinContextMetal);
|
||||
|
||||
@@ -1850,12 +1850,10 @@ class MockTexture : public Texture {
|
||||
~MockTexture() override = default;
|
||||
|
||||
// Called from raster thread.
|
||||
void Paint(SkCanvas& canvas,
|
||||
void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions&,
|
||||
const SkPaint* paint) override {}
|
||||
const SkSamplingOptions&) override {}
|
||||
|
||||
void OnGrContextCreated() override {}
|
||||
|
||||
|
||||
@@ -38,12 +38,10 @@ void AndroidExternalTextureGL::MarkNewFrameAvailable() {
|
||||
new_frame_ready_ = true;
|
||||
}
|
||||
|
||||
void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
void AndroidExternalTextureGL::Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
if (state_ == AttachmentState::detached) {
|
||||
return;
|
||||
}
|
||||
@@ -60,29 +58,29 @@ void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
GL_RGBA8_OES};
|
||||
GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo);
|
||||
sk_sp<SkImage> image = SkImage::MakeFromTexture(
|
||||
context, backendTexture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType, nullptr);
|
||||
context.gr_context, backendTexture, kTopLeft_GrSurfaceOrigin,
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
|
||||
if (image) {
|
||||
SkAutoCanvasRestore autoRestore(&canvas, true);
|
||||
SkAutoCanvasRestore autoRestore(context.canvas, true);
|
||||
|
||||
// The incoming texture is vertically flipped, so we flip it
|
||||
// back. OpenGL's coordinate system has Positive Y equivalent to up, while
|
||||
// Skia's coordinate system has Negative Y equvalent to up.
|
||||
canvas.translate(bounds.x(), bounds.y() + bounds.height());
|
||||
canvas.scale(bounds.width(), -bounds.height());
|
||||
context.canvas->translate(bounds.x(), bounds.y() + bounds.height());
|
||||
context.canvas->scale(bounds.width(), -bounds.height());
|
||||
|
||||
if (!transform.isIdentity()) {
|
||||
sk_sp<SkShader> shader = image->makeShader(
|
||||
SkTileMode::kRepeat, SkTileMode::kRepeat, sampling, transform);
|
||||
|
||||
SkPaint paintWithShader;
|
||||
if (paint) {
|
||||
paintWithShader = *paint;
|
||||
if (context.sk_paint) {
|
||||
paintWithShader = *context.sk_paint;
|
||||
}
|
||||
paintWithShader.setShader(shader);
|
||||
canvas.drawRect(SkRect::MakeWH(1, 1), paintWithShader);
|
||||
context.canvas->drawRect(SkRect::MakeWH(1, 1), paintWithShader);
|
||||
} else {
|
||||
canvas.drawImage(image, 0, 0, sampling, paint);
|
||||
context.canvas->drawImage(image, 0, 0, sampling, context.sk_paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,10 @@ class AndroidExternalTextureGL : public flutter::Texture {
|
||||
|
||||
~AndroidExternalTextureGL() override;
|
||||
|
||||
void Paint(SkCanvas& canvas,
|
||||
void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
|
||||
@@ -5,25 +5,35 @@
|
||||
assert(is_ios || is_mac)
|
||||
|
||||
import("//flutter/common/config.gni")
|
||||
import("//flutter/impeller/tools/impeller.gni")
|
||||
|
||||
source_set("graphics") {
|
||||
cflags_objc = flutter_cflags_objc_arc
|
||||
cflags_objcc = flutter_cflags_objcc_arc
|
||||
|
||||
sources = [
|
||||
"FlutterDarwinContextMetal.h",
|
||||
"FlutterDarwinContextMetal.mm",
|
||||
"FlutterDarwinContextMetalSkia.h",
|
||||
"FlutterDarwinContextMetalSkia.mm",
|
||||
"FlutterDarwinExternalTextureMetal.h",
|
||||
"FlutterDarwinExternalTextureMetal.mm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//flutter/common/graphics",
|
||||
"//flutter/display_list",
|
||||
"//flutter/fml",
|
||||
"//flutter/shell/common",
|
||||
"//flutter/shell/platform/darwin/common:framework_shared",
|
||||
]
|
||||
|
||||
if (impeller_supports_rendering) {
|
||||
sources += [
|
||||
"FlutterDarwinContextMetalImpeller.h",
|
||||
"FlutterDarwinContextMetalImpeller.mm",
|
||||
]
|
||||
deps += [ "//flutter/impeller" ]
|
||||
}
|
||||
|
||||
frameworks = [ "CoreVideo.framework" ]
|
||||
|
||||
public_deps = [ "//third_party/skia" ]
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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_IMPELLER_H_
|
||||
#define SHELL_PLATFORM_DARWIN_GRAPHICS_DARWIN_CONTEXT_METAL_IMPELLER_H_
|
||||
|
||||
#import <CoreVideo/CVMetalTextureCache.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
#include "flutter/fml/platform/darwin/cf_utils.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h"
|
||||
#include "impeller/renderer/backend/metal/context_mtl.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Provides skia GrContexts that are shared between iOS and macOS embeddings.
|
||||
*/
|
||||
@interface FlutterDarwinContextMetalImpeller : NSObject
|
||||
|
||||
/**
|
||||
* Initializes a FlutterDarwinContextMetalImpeller.
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
/**
|
||||
* Creates an external texture with the specified ID and contents.
|
||||
*/
|
||||
- (FlutterDarwinExternalTextureMetal*)
|
||||
createExternalTextureWithIdentifier:(int64_t)textureID
|
||||
texture:(NSObject<FlutterTexture>*)texture;
|
||||
/**
|
||||
* Impeller context;
|
||||
*/
|
||||
@property(nonatomic, readonly) std::shared_ptr<impeller::ContextMTL> context;
|
||||
|
||||
/*
|
||||
* Texture cache for external textures.
|
||||
*/
|
||||
@property(nonatomic, readonly) fml::CFRef<CVMetalTextureCacheRef> textureCache;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // SHELL_PLATFORM_DARWIN_GRAPHICS_DARWIN_CONTEXT_METAL_IMPELLER_H_
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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/FlutterDarwinContextMetalImpeller.h"
|
||||
|
||||
#include "flutter/common/graphics/persistent_cache.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/impeller/entity/mtl/entity_shaders.h"
|
||||
#include "flutter/impeller/renderer/backend/metal/context_mtl.h"
|
||||
#include "flutter/shell/common/context_options.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
|
||||
|
||||
FLUTTER_ASSERT_ARC
|
||||
|
||||
static std::shared_ptr<impeller::ContextMTL> CreateImpellerContext() {
|
||||
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_data,
|
||||
impeller_entity_shaders_length),
|
||||
};
|
||||
auto context = impeller::ContextMTL::Create(shader_mappings, "Impeller Library");
|
||||
if (!context) {
|
||||
FML_LOG(ERROR) << "Could not create Metal Impeller Context.";
|
||||
return nullptr;
|
||||
}
|
||||
FML_LOG(ERROR) << "Using the Impeller rendering backend.";
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
@implementation FlutterDarwinContextMetalImpeller
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_context = CreateImpellerContext();
|
||||
id<MTLDevice> device = _context->GetMTLDevice();
|
||||
if (!device) {
|
||||
FML_DLOG(ERROR) << "Could not acquire Metal device.";
|
||||
return nil;
|
||||
}
|
||||
|
||||
CVMetalTextureCacheRef textureCache;
|
||||
CVReturn cvReturn = CVMetalTextureCacheCreate(kCFAllocatorDefault, // allocator
|
||||
nil, // cache attributes (nil default)
|
||||
device, // metal device
|
||||
nil, // texture attributes (nil default)
|
||||
&textureCache // [out] cache
|
||||
);
|
||||
|
||||
if (cvReturn != kCVReturnSuccess) {
|
||||
FML_DLOG(ERROR) << "Could not create Metal texture cache.";
|
||||
return nil;
|
||||
}
|
||||
_textureCache.Reset(textureCache);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (FlutterDarwinExternalTextureMetal*)
|
||||
createExternalTextureWithIdentifier:(int64_t)textureID
|
||||
texture:(NSObject<FlutterTexture>*)texture {
|
||||
return [[FlutterDarwinExternalTextureMetal alloc] initWithTextureCache:_textureCache
|
||||
textureID:textureID
|
||||
texture:texture
|
||||
enableImpeller:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -18,16 +18,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* Provides skia GrContexts that are shared between iOS and macOS embeddings.
|
||||
*/
|
||||
@interface FlutterDarwinContextMetal : NSObject
|
||||
@interface FlutterDarwinContextMetalSkia : NSObject
|
||||
|
||||
/**
|
||||
* Initializes a FlutterDarwinContextMetal with the system default MTLDevice and a new
|
||||
* Initializes a FlutterDarwinContextMetalSkia with the system default MTLDevice and a new
|
||||
* MTLCommandQueue.
|
||||
*/
|
||||
- (instancetype)initWithDefaultMTLDevice;
|
||||
|
||||
/**
|
||||
* Initializes a FlutterDarwinContextMetal with provided MTLDevice and MTLCommandQueue.
|
||||
* Initializes a FlutterDarwinContextMetalSkia with provided MTLDevice and MTLCommandQueue.
|
||||
*/
|
||||
- (instancetype)initWithMTLDevice:(id<MTLDevice>)device
|
||||
commandQueue:(id<MTLCommandQueue>)commandQueue;
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
|
||||
#include "flutter/common/graphics/persistent_cache.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
FLUTTER_ASSERT_ARC
|
||||
|
||||
@implementation FlutterDarwinContextMetal
|
||||
@implementation FlutterDarwinContextMetalSkia
|
||||
|
||||
- (instancetype)initWithDefaultMTLDevice {
|
||||
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
@@ -70,7 +70,7 @@ FLUTTER_ASSERT_ARC
|
||||
flutter::MakeDefaultContextOptions(flutter::ContextType::kRender, GrBackendApi::kMetal);
|
||||
id<MTLDevice> device = _device;
|
||||
id<MTLCommandQueue> commandQueue = _commandQueue;
|
||||
return [FlutterDarwinContextMetal createGrContext:device commandQueue:commandQueue];
|
||||
return [FlutterDarwinContextMetalSkia createGrContext:device commandQueue:commandQueue];
|
||||
}
|
||||
|
||||
+ (sk_sp<GrDirectContext>)createGrContext:(id<MTLDevice>)device
|
||||
@@ -94,7 +94,8 @@ FLUTTER_ASSERT_ARC
|
||||
texture:(NSObject<FlutterTexture>*)texture {
|
||||
return [[FlutterDarwinExternalTextureMetal alloc] initWithTextureCache:_textureCache
|
||||
textureID:textureID
|
||||
texture:texture];
|
||||
texture:texture
|
||||
enableImpeller:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -5,6 +5,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
#include "flutter/common/graphics/texture.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkImage.h"
|
||||
@@ -29,14 +30,13 @@
|
||||
|
||||
- (nullable instancetype)initWithTextureCache:(nonnull CVMetalTextureCacheRef)textureCache
|
||||
textureID:(int64_t)textureID
|
||||
texture:(nonnull NSObject<FlutterTexture>*)texture;
|
||||
texture:(nonnull NSObject<FlutterTexture>*)texture
|
||||
enableImpeller:(BOOL)enableImpeller;
|
||||
|
||||
- (void)canvas:(SkCanvas&)canvas
|
||||
bounds:(const SkRect&)bounds
|
||||
freeze:(BOOL)freeze
|
||||
grContext:(nonnull GrDirectContext*)grContext
|
||||
sampling:(const SkSamplingOptions&)sampling
|
||||
paint:(nullable const SkPaint*)paint;
|
||||
- (void)paintContext:(flutter::Texture::PaintContext&)context
|
||||
bounds:(const SkRect&)bounds
|
||||
freeze:(BOOL)freeze
|
||||
sampling:(const SkSamplingOptions&)sampling;
|
||||
|
||||
- (void)onGrContextCreated;
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h"
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
|
||||
#include "flutter/display_list/display_list_image.h"
|
||||
#include "impeller/base/validation.h"
|
||||
#include "impeller/display_list/display_list_image_impeller.h"
|
||||
#include "impeller/renderer/backend/metal/texture_mtl.h"
|
||||
#include "third_party/skia/include/core/SkColorSpace.h"
|
||||
#include "third_party/skia/include/core/SkYUVAInfo.h"
|
||||
#include "third_party/skia/include/gpu/GrBackendSurface.h"
|
||||
@@ -19,19 +20,22 @@ FLUTTER_ASSERT_ARC
|
||||
CVMetalTextureCacheRef _textureCache;
|
||||
NSObject<FlutterTexture>* _externalTexture;
|
||||
BOOL _textureFrameAvailable;
|
||||
sk_sp<SkImage> _externalImage;
|
||||
sk_sp<flutter::DlImage> _externalImage;
|
||||
CVPixelBufferRef _lastPixelBuffer;
|
||||
OSType _pixelFormat;
|
||||
BOOL _enableImpeller;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTextureCache:(nonnull CVMetalTextureCacheRef)textureCache
|
||||
textureID:(int64_t)textureID
|
||||
texture:(NSObject<FlutterTexture>*)texture {
|
||||
texture:(NSObject<FlutterTexture>*)texture
|
||||
enableImpeller:(BOOL)enableImpeller {
|
||||
if (self = [super init]) {
|
||||
_textureCache = textureCache;
|
||||
CFRetain(_textureCache);
|
||||
_textureID = textureID;
|
||||
_externalTexture = texture;
|
||||
_enableImpeller = enableImpeller;
|
||||
return self;
|
||||
}
|
||||
return nil;
|
||||
@@ -47,30 +51,41 @@ FLUTTER_ASSERT_ARC
|
||||
}
|
||||
}
|
||||
|
||||
- (void)canvas:(SkCanvas&)canvas
|
||||
bounds:(const SkRect&)bounds
|
||||
freeze:(BOOL)freeze
|
||||
grContext:(nonnull GrDirectContext*)grContext
|
||||
sampling:(const SkSamplingOptions&)sampling
|
||||
paint:(nullable const SkPaint*)paint {
|
||||
- (void)paintContext:(flutter::Texture::PaintContext&)context
|
||||
bounds:(const SkRect&)bounds
|
||||
freeze:(BOOL)freeze
|
||||
sampling:(const SkSamplingOptions&)sampling {
|
||||
const bool needsUpdatedTexture = (!freeze && _textureFrameAvailable) || !_externalImage;
|
||||
|
||||
if (needsUpdatedTexture) {
|
||||
[self onNeedsUpdatedTexture:grContext];
|
||||
[self onNeedsUpdatedTexture:context];
|
||||
}
|
||||
|
||||
if (_externalImage) {
|
||||
canvas.drawImageRect(_externalImage, // image
|
||||
SkRect::Make(_externalImage->bounds()), // source rect
|
||||
bounds, // destination rect
|
||||
sampling, // sampling
|
||||
paint, // paint
|
||||
SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint // constraint
|
||||
if (_enableImpeller) {
|
||||
context.builder->drawImageRect(
|
||||
_externalImage, // image
|
||||
SkRect::Make(_externalImage->bounds()), // source rect
|
||||
bounds, // destination rect
|
||||
flutter::ToDl(sampling), // sampling
|
||||
context.dl_paint, // paint
|
||||
SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint // constraint
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
context.canvas->drawImageRect(
|
||||
_externalImage->skia_image(), // image
|
||||
SkRect::Make(_externalImage->bounds()), // source rect
|
||||
bounds, // destination rect
|
||||
sampling, // sampling
|
||||
context.sk_paint, // paint
|
||||
SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint // constraint
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onNeedsUpdatedTexture:(nonnull GrDirectContext*)grContext {
|
||||
- (void)onNeedsUpdatedTexture:(flutter::Texture::PaintContext&)context {
|
||||
CVPixelBufferRef pixelBuffer = [_externalTexture copyPixelBuffer];
|
||||
if (pixelBuffer) {
|
||||
CVPixelBufferRelease(_lastPixelBuffer);
|
||||
@@ -80,7 +95,7 @@ FLUTTER_ASSERT_ARC
|
||||
|
||||
// If the application told us there was a texture frame available but did not provide one when
|
||||
// asked for it, reuse the previous texture but make sure to ask again the next time around.
|
||||
sk_sp<SkImage> image = [self wrapExternalPixelBuffer:_lastPixelBuffer grContext:grContext];
|
||||
sk_sp<flutter::DlImage> image = [self wrapExternalPixelBuffer:_lastPixelBuffer context:context];
|
||||
if (image) {
|
||||
_externalImage = image;
|
||||
_textureFrameAvailable = false;
|
||||
@@ -116,29 +131,35 @@ FLUTTER_ASSERT_ARC
|
||||
|
||||
#pragma mark - External texture skia wrapper methods.
|
||||
|
||||
- (sk_sp<SkImage>)wrapExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||
grContext:(GrDirectContext*)grContext {
|
||||
- (sk_sp<flutter::DlImage>)wrapExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||
context:(flutter::Texture::PaintContext&)context {
|
||||
if (!pixelBuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> image = nullptr;
|
||||
sk_sp<flutter::DlImage> image = nullptr;
|
||||
if (_pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
||||
_pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
|
||||
image = [self wrapNV12ExternalPixelBuffer:pixelBuffer grContext:grContext];
|
||||
image = [self wrapNV12ExternalPixelBuffer:pixelBuffer context:context];
|
||||
} else {
|
||||
image = [self wrapRGBAExternalPixelBuffer:pixelBuffer grContext:grContext];
|
||||
image = [self wrapRGBAExternalPixelBuffer:pixelBuffer context:context];
|
||||
}
|
||||
|
||||
if (!image) {
|
||||
FML_DLOG(ERROR) << "Could not wrap Metal texture as a Skia image.";
|
||||
FML_DLOG(ERROR) << "Could not wrap Metal texture as a display list image.";
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
- (sk_sp<SkImage>)wrapNV12ExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||
grContext:(GrDirectContext*)grContext {
|
||||
- (sk_sp<flutter::DlImage>)wrapNV12ExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||
context:(flutter::Texture::PaintContext&)context {
|
||||
if (_enableImpeller) {
|
||||
// TODO(113688): Support YUV external textures.
|
||||
VALIDATION_LOG << "YUV external texture support is not implemented yet.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SkISize textureSize =
|
||||
SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
|
||||
CVMetalTextureRef yMetalTexture = nullptr;
|
||||
@@ -188,16 +209,21 @@ FLUTTER_ASSERT_ARC
|
||||
SkYUVColorSpace colorSpace = _pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
|
||||
? kRec601_Limited_SkYUVColorSpace
|
||||
: kJPEG_Full_SkYUVColorSpace;
|
||||
return [FlutterDarwinExternalTextureSkImageWrapper wrapYUVATexture:yTex
|
||||
UVTex:uvTex
|
||||
YUVColorSpace:colorSpace
|
||||
grContext:grContext
|
||||
width:textureSize.width()
|
||||
height:textureSize.height()];
|
||||
auto skImage = [FlutterDarwinExternalTextureSkImageWrapper wrapYUVATexture:yTex
|
||||
UVTex:uvTex
|
||||
YUVColorSpace:colorSpace
|
||||
grContext:context.gr_context
|
||||
width:textureSize.width()
|
||||
height:textureSize.height()];
|
||||
if (!skImage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return flutter::DlImage::Make(skImage);
|
||||
}
|
||||
|
||||
- (sk_sp<SkImage>)wrapRGBAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||
grContext:(GrDirectContext*)grContext {
|
||||
- (sk_sp<flutter::DlImage>)wrapRGBAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||
context:(flutter::Texture::PaintContext&)context {
|
||||
SkISize textureSize =
|
||||
SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
|
||||
CVMetalTextureRef metalTexture = nullptr;
|
||||
@@ -220,10 +246,25 @@ FLUTTER_ASSERT_ARC
|
||||
id<MTLTexture> rgbaTex = CVMetalTextureGetTexture(metalTexture);
|
||||
CVBufferRelease(metalTexture);
|
||||
|
||||
return [FlutterDarwinExternalTextureSkImageWrapper wrapRGBATexture:rgbaTex
|
||||
grContext:grContext
|
||||
width:textureSize.width()
|
||||
height:textureSize.height()];
|
||||
if (_enableImpeller) {
|
||||
impeller::TextureDescriptor desc;
|
||||
desc.storage_mode = impeller::StorageMode::kHostVisible;
|
||||
desc.format = impeller::PixelFormat::kB8G8R8A8UNormInt;
|
||||
desc.size = {textureSize.width(), textureSize.height()};
|
||||
desc.mip_count = 1;
|
||||
auto texture = impeller::TextureMTL::Wrapper(desc, rgbaTex);
|
||||
texture->SetIntent(impeller::TextureIntent::kUploadFromHost);
|
||||
return impeller::DlImageImpeller::Make(texture);
|
||||
}
|
||||
|
||||
auto skImage = [FlutterDarwinExternalTextureSkImageWrapper wrapRGBATexture:rgbaTex
|
||||
grContext:context.gr_context
|
||||
width:textureSize.width()
|
||||
height:textureSize.height()];
|
||||
if (!skImage) {
|
||||
return nullptr;
|
||||
}
|
||||
return flutter::DlImage::Make(skImage);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_CONTEXT_METAL_IMPELER_H_
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h"
|
||||
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
#include "flutter/shell/platform/darwin/ios/ios_context.h"
|
||||
|
||||
namespace impeller {
|
||||
@@ -23,7 +24,7 @@ class IOSContextMetalImpeller final : public IOSContext {
|
||||
|
||||
~IOSContextMetalImpeller();
|
||||
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> GetDarwinContext() const;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalSkia> GetDarwinContext() const;
|
||||
|
||||
IOSRenderingBackend GetBackend() const override;
|
||||
|
||||
@@ -33,7 +34,7 @@ class IOSContextMetalImpeller final : public IOSContext {
|
||||
sk_sp<GrDirectContext> GetResourceContext() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<impeller::Context> context_;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalImpeller> darwin_context_metal_impeller_;
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> CreateResourceContext() override;
|
||||
|
||||
@@ -3,33 +3,21 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h"
|
||||
|
||||
#include "flutter/impeller/entity/mtl/entity_shaders.h"
|
||||
#include "flutter/impeller/renderer/backend/metal/context_mtl.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
static std::shared_ptr<impeller::Context> CreateImpellerContext() {
|
||||
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_data,
|
||||
impeller_entity_shaders_length),
|
||||
};
|
||||
auto context = impeller::ContextMTL::Create(shader_mappings, "Impeller Library");
|
||||
if (!context) {
|
||||
FML_LOG(ERROR) << "Could not create Metal Impeller Context.";
|
||||
return nullptr;
|
||||
}
|
||||
FML_LOG(ERROR) << "Using the Impeller rendering backend.";
|
||||
return context;
|
||||
}
|
||||
|
||||
IOSContextMetalImpeller::IOSContextMetalImpeller()
|
||||
: IOSContext(MsaaSampleCount::kFour), context_(CreateImpellerContext()) {}
|
||||
: IOSContext(MsaaSampleCount::kFour),
|
||||
darwin_context_metal_impeller_(fml::scoped_nsobject<FlutterDarwinContextMetalImpeller>{
|
||||
[[FlutterDarwinContextMetalImpeller alloc] init]}) {}
|
||||
|
||||
IOSContextMetalImpeller::~IOSContextMetalImpeller() = default;
|
||||
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> IOSContextMetalImpeller::GetDarwinContext() const {
|
||||
return fml::scoped_nsobject<FlutterDarwinContextMetal>{};
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalSkia> IOSContextMetalImpeller::GetDarwinContext()
|
||||
const {
|
||||
return fml::scoped_nsobject<FlutterDarwinContextMetalSkia>{};
|
||||
}
|
||||
|
||||
IOSRenderingBackend IOSContextMetalImpeller::GetBackend() const {
|
||||
@@ -51,7 +39,7 @@ sk_sp<GrDirectContext> IOSContextMetalImpeller::CreateResourceContext() {
|
||||
|
||||
// |IOSContext|
|
||||
std::shared_ptr<impeller::Context> IOSContextMetalImpeller::GetImpellerContext() const {
|
||||
return context_;
|
||||
return darwin_context_metal_impeller_.get().context;
|
||||
}
|
||||
|
||||
// |IOSContext|
|
||||
@@ -64,7 +52,10 @@ std::unique_ptr<GLContextResult> IOSContextMetalImpeller::MakeCurrent() {
|
||||
std::unique_ptr<Texture> IOSContextMetalImpeller::CreateExternalTexture(
|
||||
int64_t texture_id,
|
||||
fml::scoped_nsobject<NSObject<FlutterTexture>> texture) {
|
||||
return nullptr;
|
||||
return std::make_unique<IOSExternalTextureMetal>(
|
||||
fml::scoped_nsobject<FlutterDarwinExternalTextureMetal>{
|
||||
[[darwin_context_metal_impeller_ createExternalTextureWithIdentifier:texture_id
|
||||
texture:texture] retain]});
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -10,7 +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/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context.h"
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
|
||||
@@ -22,7 +22,7 @@ class IOSContextMetalSkia final : public IOSContext {
|
||||
|
||||
~IOSContextMetalSkia();
|
||||
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> GetDarwinContext() const;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalSkia> GetDarwinContext() const;
|
||||
|
||||
// |IOSContext|
|
||||
IOSRenderingBackend GetBackend() const override;
|
||||
@@ -33,7 +33,7 @@ class IOSContextMetalSkia final : public IOSContext {
|
||||
sk_sp<GrDirectContext> GetResourceContext() const;
|
||||
|
||||
private:
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> darwin_context_metal_;
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalSkia> darwin_context_metal_;
|
||||
|
||||
// |IOSContext|
|
||||
sk_sp<GrDirectContext> CreateResourceContext() override;
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
|
||||
#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/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h"
|
||||
#include "third_party/skia/include/gpu/GrContextOptions.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSContextMetalSkia::IOSContextMetalSkia(MsaaSampleCount msaa_samples) : IOSContext(msaa_samples) {
|
||||
darwin_context_metal_ = fml::scoped_nsobject<FlutterDarwinContextMetal>{
|
||||
[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice]};
|
||||
darwin_context_metal_ = fml::scoped_nsobject<FlutterDarwinContextMetalSkia>{
|
||||
[[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]};
|
||||
}
|
||||
|
||||
IOSContextMetalSkia::~IOSContextMetalSkia() = default;
|
||||
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetal> IOSContextMetalSkia::GetDarwinContext() const {
|
||||
fml::scoped_nsobject<FlutterDarwinContextMetalSkia> IOSContextMetalSkia::GetDarwinContext() const {
|
||||
return darwin_context_metal_;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,10 @@ class IOSExternalTextureMetal final : public Texture {
|
||||
darwin_external_texture_metal_;
|
||||
|
||||
// |Texture|
|
||||
void Paint(SkCanvas& canvas,
|
||||
void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
// |Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h"
|
||||
#include "flow/layers/layer.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
@@ -13,18 +14,14 @@ IOSExternalTextureMetal::IOSExternalTextureMetal(
|
||||
|
||||
IOSExternalTextureMetal::~IOSExternalTextureMetal() = default;
|
||||
|
||||
void IOSExternalTextureMetal::Paint(SkCanvas& canvas,
|
||||
void IOSExternalTextureMetal::Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) {
|
||||
[darwin_external_texture_metal_ canvas:canvas
|
||||
bounds:bounds
|
||||
freeze:freeze
|
||||
grContext:context
|
||||
sampling:sampling
|
||||
paint:paint];
|
||||
const SkSamplingOptions& sampling) {
|
||||
[darwin_external_texture_metal_ paintContext:context
|
||||
bounds:bounds
|
||||
freeze:freeze
|
||||
sampling:sampling];
|
||||
}
|
||||
|
||||
void IOSExternalTextureMetal::OnGrContextCreated() {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h"
|
||||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h"
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
@@ -71,8 +71,8 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestTextureResolution) {
|
||||
const int64_t texture_id = 1;
|
||||
|
||||
// Set up the surface.
|
||||
FlutterDarwinContextMetal* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice];
|
||||
FlutterDarwinContextMetalSkia* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
GrDirectContext* grContext = darwinContextMetal.mainContext.get();
|
||||
sk_sp<SkSurface> gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
|
||||
@@ -111,7 +111,11 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestTextureResolution) {
|
||||
std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
|
||||
SkRect bounds = SkRect::MakeWH(info.width(), info.height());
|
||||
SkSamplingOptions sampling = SkSamplingOptions(SkFilterMode::kNearest);
|
||||
texture->Paint(*gpuSurface->getCanvas(), bounds, /*freeze=*/false, grContext, sampling);
|
||||
flutter::Texture::PaintContext context{
|
||||
.canvas = gpuSurface->getCanvas(),
|
||||
.gr_context = grContext,
|
||||
};
|
||||
texture->Paint(context, bounds, /*freeze=*/false, sampling);
|
||||
|
||||
ASSERT_TRUE(mtlTexture != nil);
|
||||
|
||||
@@ -125,8 +129,8 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTexture) {
|
||||
const int64_t texture_id = 1;
|
||||
|
||||
// Set up the surface.
|
||||
FlutterDarwinContextMetal* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice];
|
||||
FlutterDarwinContextMetalSkia* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
GrDirectContext* grContext = darwinContextMetal.mainContext.get();
|
||||
sk_sp<SkSurface> gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
|
||||
@@ -161,7 +165,11 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTexture) {
|
||||
std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
|
||||
SkRect bounds = SkRect::MakeWH(info.width(), info.height());
|
||||
SkSamplingOptions sampling = SkSamplingOptions(SkFilterMode::kNearest);
|
||||
texture->Paint(*gpuSurface->getCanvas(), bounds, /*freeze=*/false, grContext, sampling);
|
||||
flutter::Texture::PaintContext context{
|
||||
.canvas = gpuSurface->getCanvas(),
|
||||
.gr_context = grContext,
|
||||
};
|
||||
texture->Paint(context, bounds, /*freeze=*/false, sampling);
|
||||
|
||||
gpuSurface->makeImageSnapshot();
|
||||
}
|
||||
@@ -173,8 +181,8 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA) {
|
||||
const int64_t texture_id = 1;
|
||||
|
||||
// Set up the surface.
|
||||
FlutterDarwinContextMetal* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice];
|
||||
FlutterDarwinContextMetalSkia* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
GrDirectContext* grContext = darwinContextMetal.mainContext.get();
|
||||
sk_sp<SkSurface> gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
|
||||
@@ -211,7 +219,11 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA) {
|
||||
std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
|
||||
SkRect bounds = SkRect::MakeWH(info.width(), info.height());
|
||||
SkSamplingOptions sampling = SkSamplingOptions(SkFilterMode::kNearest);
|
||||
texture->Paint(*gpuSurface->getCanvas(), bounds, /*freeze=*/false, grContext, sampling);
|
||||
flutter::Texture::PaintContext context{
|
||||
.canvas = gpuSurface->getCanvas(),
|
||||
.gr_context = grContext,
|
||||
};
|
||||
texture->Paint(context, bounds, /*freeze=*/false, sampling);
|
||||
|
||||
gpuSurface->makeImageSnapshot();
|
||||
}
|
||||
@@ -223,8 +235,8 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA2)
|
||||
const int64_t texture_id = 1;
|
||||
|
||||
// Set up the surface.
|
||||
FlutterDarwinContextMetal* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice];
|
||||
FlutterDarwinContextMetalSkia* darwinContextMetal =
|
||||
[[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
GrDirectContext* grContext = darwinContextMetal.mainContext.get();
|
||||
sk_sp<SkSurface> gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info));
|
||||
@@ -261,7 +273,11 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA2)
|
||||
std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
|
||||
SkRect bounds = SkRect::MakeWH(info.width(), info.height());
|
||||
SkSamplingOptions sampling = SkSamplingOptions(SkFilterMode::kNearest);
|
||||
texture->Paint(*gpuSurface->getCanvas(), bounds, /*freeze=*/false, grContext, sampling);
|
||||
flutter::Texture::PaintContext context{
|
||||
.canvas = gpuSurface->getCanvas(),
|
||||
.gr_context = grContext,
|
||||
};
|
||||
texture->Paint(context, bounds, /*freeze=*/false, sampling);
|
||||
|
||||
gpuSurface->makeImageSnapshot();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMacOSExternalTexture.h"
|
||||
|
||||
/**
|
||||
@@ -17,7 +17,7 @@
|
||||
* Initializes a texture adapter with |texture|.
|
||||
*/
|
||||
- (nonnull instancetype)initWithFlutterTexture:(nonnull id<FlutterTexture>)texture
|
||||
darwinMetalContext:(nonnull FlutterDarwinContextMetal*)context;
|
||||
darwinMetalContext:(nonnull FlutterDarwinContextMetalSkia*)context;
|
||||
|
||||
/**
|
||||
* Accepts texture buffer copy request from the Flutter engine.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "flutter/fml/platform/darwin/cf_utils.h"
|
||||
|
||||
@implementation FlutterExternalTextureMetal {
|
||||
FlutterDarwinContextMetal* _darwinMetalContext;
|
||||
FlutterDarwinContextMetalSkia* _darwinMetalContext;
|
||||
|
||||
int64_t _textureID;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
- (instancetype)initWithFlutterTexture:(id<FlutterTexture>)texture
|
||||
darwinMetalContext:(FlutterDarwinContextMetal*)context {
|
||||
darwinMetalContext:(FlutterDarwinContextMetalSkia*)context {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_texture = texture;
|
||||
|
||||
@@ -37,7 +37,7 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
|
||||
@implementation FlutterMetalRenderer {
|
||||
FlutterView* _flutterView;
|
||||
|
||||
FlutterDarwinContextMetal* _darwinMetalContext;
|
||||
FlutterDarwinContextMetalSkia* _darwinMetalContext;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine {
|
||||
@@ -55,8 +55,8 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
|
||||
return nil;
|
||||
}
|
||||
|
||||
_darwinMetalContext = [[FlutterDarwinContextMetal alloc] initWithMTLDevice:_device
|
||||
commandQueue:_commandQueue];
|
||||
_darwinMetalContext = [[FlutterDarwinContextMetalSkia alloc] initWithMTLDevice:_device
|
||||
commandQueue:_commandQueue];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "third_party/skia/include/core/SkAlphaType.h"
|
||||
#include "third_party/skia/include/core/SkColorSpace.h"
|
||||
#include "third_party/skia/include/core/SkColorType.h"
|
||||
@@ -25,20 +27,21 @@ EmbedderExternalTextureGL::EmbedderExternalTextureGL(
|
||||
EmbedderExternalTextureGL::~EmbedderExternalTextureGL() = default;
|
||||
|
||||
// |flutter::Texture|
|
||||
void EmbedderExternalTextureGL::Paint(SkCanvas& canvas,
|
||||
void EmbedderExternalTextureGL::Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
if (last_image_ == nullptr) {
|
||||
last_image_ =
|
||||
ResolveTexture(Id(), //
|
||||
context, //
|
||||
context.gr_context, //
|
||||
SkISize::Make(bounds.width(), bounds.height()) //
|
||||
);
|
||||
}
|
||||
|
||||
SkCanvas& canvas = *context.canvas;
|
||||
const SkPaint* paint = context.sk_paint;
|
||||
|
||||
if (last_image_) {
|
||||
if (bounds != SkRect::Make(last_image_->bounds())) {
|
||||
canvas.drawImageRect(last_image_, bounds, sampling, paint);
|
||||
|
||||
@@ -32,12 +32,10 @@ class EmbedderExternalTextureGL : public flutter::Texture {
|
||||
const SkISize& size);
|
||||
|
||||
// |flutter::Texture|
|
||||
void Paint(SkCanvas& canvas,
|
||||
void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
// |flutter::Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
@@ -32,12 +32,10 @@ class EmbedderExternalTextureMetal : public flutter::Texture {
|
||||
const SkISize& size);
|
||||
|
||||
// |flutter::Texture|
|
||||
void Paint(SkCanvas& canvas,
|
||||
void Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) override;
|
||||
const SkSamplingOptions& sampling) override;
|
||||
|
||||
// |flutter::Texture|
|
||||
void OnGrContextCreated() override;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "flutter/shell/platform/embedder/embedder_external_texture_metal.h"
|
||||
|
||||
#include "flow/layers/layer.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h"
|
||||
#include "third_party/skia/include/core/SkImage.h"
|
||||
@@ -31,16 +32,18 @@ EmbedderExternalTextureMetal::EmbedderExternalTextureMetal(int64_t texture_ident
|
||||
EmbedderExternalTextureMetal::~EmbedderExternalTextureMetal() = default;
|
||||
|
||||
// |flutter::Texture|
|
||||
void EmbedderExternalTextureMetal::Paint(SkCanvas& canvas,
|
||||
void EmbedderExternalTextureMetal::Paint(PaintContext& context,
|
||||
const SkRect& bounds,
|
||||
bool freeze,
|
||||
GrDirectContext* context,
|
||||
const SkSamplingOptions& sampling,
|
||||
const SkPaint* paint) {
|
||||
const SkSamplingOptions& sampling) {
|
||||
if (last_image_ == nullptr) {
|
||||
last_image_ = ResolveTexture(Id(), context, SkISize::Make(bounds.width(), bounds.height()));
|
||||
last_image_ =
|
||||
ResolveTexture(Id(), context.gr_context, SkISize::Make(bounds.width(), bounds.height()));
|
||||
}
|
||||
|
||||
SkCanvas& canvas = *context.canvas;
|
||||
const SkPaint* paint = context.sk_paint;
|
||||
|
||||
if (last_image_) {
|
||||
if (bounds != SkRect::Make(last_image_->bounds())) {
|
||||
canvas.drawImageRect(last_image_, bounds, sampling, paint);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_metal_delegate.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h"
|
||||
#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
|
||||
FLUTTER_ASSERT_NOT_ARC
|
||||
@@ -22,11 +22,12 @@ EmbedderSurfaceMetal::EmbedderSurfaceMetal(
|
||||
: GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture),
|
||||
metal_dispatch_table_(std::move(metal_dispatch_table)),
|
||||
external_view_embedder_(std::move(external_view_embedder)) {
|
||||
main_context_ = [FlutterDarwinContextMetal createGrContext:(id<MTLDevice>)device
|
||||
commandQueue:(id<MTLCommandQueue>)command_queue];
|
||||
main_context_ =
|
||||
[FlutterDarwinContextMetalSkia createGrContext:(id<MTLDevice>)device
|
||||
commandQueue:(id<MTLCommandQueue>)command_queue];
|
||||
resource_context_ =
|
||||
[FlutterDarwinContextMetal createGrContext:(id<MTLDevice>)device
|
||||
commandQueue:(id<MTLCommandQueue>)command_queue];
|
||||
[FlutterDarwinContextMetalSkia createGrContext:(id<MTLDevice>)device
|
||||
commandQueue:(id<MTLCommandQueue>)command_queue];
|
||||
valid_ = main_context_ && resource_context_;
|
||||
}
|
||||
|
||||
|
||||
@@ -4047,20 +4047,24 @@ TEST_F(EmbedderTest, ExternalTextureGLRefreshedTooOften) {
|
||||
auto canvas = skia_surface->getCanvas();
|
||||
|
||||
Texture* texture_ = &texture;
|
||||
texture_->Paint(*canvas, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
context.get(), SkSamplingOptions(SkFilterMode::kLinear));
|
||||
Texture::PaintContext ctx{
|
||||
.canvas = canvas,
|
||||
.gr_context = context.get(),
|
||||
};
|
||||
texture_->Paint(ctx, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
EXPECT_TRUE(resolve_called);
|
||||
resolve_called = false;
|
||||
|
||||
texture_->Paint(*canvas, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
context.get(), SkSamplingOptions(SkFilterMode::kLinear));
|
||||
texture_->Paint(ctx, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
EXPECT_FALSE(resolve_called);
|
||||
|
||||
texture_->MarkNewFrameAvailable();
|
||||
texture_->Paint(*canvas, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
context.get(), SkSamplingOptions(SkFilterMode::kLinear));
|
||||
texture_->Paint(ctx, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
EXPECT_TRUE(resolve_called);
|
||||
}
|
||||
|
||||
@@ -465,20 +465,24 @@ TEST_F(EmbedderTest, ExternalTextureMetalRefreshedTooOften) {
|
||||
auto canvas = skia_surface->getCanvas();
|
||||
|
||||
Texture* texture_ = &texture;
|
||||
texture_->Paint(*canvas, SkRect::MakeXYWH(0, 0, 100, 100), false, surface->GetGrContext().get(),
|
||||
Texture::PaintContext ctx{
|
||||
.canvas = canvas,
|
||||
.gr_context = surface->GetGrContext().get(),
|
||||
};
|
||||
texture_->Paint(ctx, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
EXPECT_TRUE(resolve_called);
|
||||
resolve_called = false;
|
||||
|
||||
texture_->Paint(*canvas, SkRect::MakeXYWH(0, 0, 100, 100), false, surface->GetGrContext().get(),
|
||||
texture_->Paint(ctx, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
EXPECT_FALSE(resolve_called);
|
||||
|
||||
texture_->MarkNewFrameAvailable();
|
||||
|
||||
texture_->Paint(*canvas, SkRect::MakeXYWH(0, 0, 100, 100), false, surface->GetGrContext().get(),
|
||||
texture_->Paint(ctx, SkRect::MakeXYWH(0, 0, 100, 100), false,
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
|
||||
EXPECT_TRUE(resolve_called);
|
||||
|
||||
Reference in New Issue
Block a user