From c7fc4800870b6a23b070bb80b046285c5933c94d Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Wed, 28 Sep 2022 17:58:39 +0800 Subject: [PATCH 1/7] Tweak Texture::Paint API --- common/graphics/BUILD.gn | 1 + common/graphics/texture.h | 17 +++++++++---- flow/layers/texture_layer.cc | 8 +++++-- flow/testing/mock_texture.cc | 12 +++++----- flow/testing/mock_texture.h | 6 ++--- flow/testing/mock_texture_unittests.cc | 16 ++++++++----- impeller/renderer/backend/metal/texture_mtl.h | 9 ++++++- .../renderer/backend/metal/texture_mtl.mm | 16 +++++++++++-- shell/common/shell_unittests.cc | 6 ++--- .../android/android_external_texture_gl.cc | 24 +++++++++---------- .../android/android_external_texture_gl.h | 6 ++--- .../darwin/ios/ios_external_texture_metal.h | 6 ++--- .../darwin/ios/ios_external_texture_metal.mm | 13 +++++----- ...FlutterEmbedderExternalTextureUnittests.mm | 24 +++++++++++++++---- .../embedder/embedder_external_texture_gl.cc | 13 ++++++---- .../embedder/embedder_external_texture_gl.h | 6 ++--- .../embedder_external_texture_metal.h | 6 ++--- .../embedder_external_texture_metal.mm | 13 ++++++---- .../embedder/tests/embedder_unittests_gl.cc | 16 ++++++++----- .../tests/embedder_unittests_metal.mm | 10 +++++--- 20 files changed, 140 insertions(+), 88 deletions(-) diff --git a/common/graphics/BUILD.gn b/common/graphics/BUILD.gn index 772e8711f4a0d..480aefb234342 100644 --- a/common/graphics/BUILD.gn +++ b/common/graphics/BUILD.gn @@ -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", diff --git a/common/graphics/texture.h b/common/graphics/texture.h index 0edb84526f994..da17bfadeeca1 100644 --- a/common/graphics/texture.h +++ b/common/graphics/texture.h @@ -7,6 +7,8 @@ #include +#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,23 @@ 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; + bool enable_impeller = false; + }; + 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; diff --git a/flow/layers/texture_layer.cc b/flow/layers/texture_layer.cc index 7ece96ebd4364..f9c95d7f025ee 100644 --- a/flow/layers/texture_layer.cc +++ b/flow/layers/texture_layer.cc @@ -62,8 +62,12 @@ 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 diff --git a/flow/testing/mock_texture.cc b/flow/testing/mock_texture.cc index ccb11e85437f1..3fe4fd116813c 100644 --- a/flow/testing/mock_texture.cc +++ b/flow/testing/mock_texture.cc @@ -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, diff --git a/flow/testing/mock_texture.h b/flow/testing/mock_texture.h index ee4ba6d460a61..8b1dfb05b493d 100644 --- a/flow/testing/mock_texture.h +++ b/flow/testing/mock_texture.h @@ -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; } diff --git a/flow/testing/mock_texture_unittests.cc b/flow/testing/mock_texture_unittests.cc index 5968928b6cd2c..5dd12f82cfeea 100644 --- a/flow/testing/mock_texture_unittests.cc +++ b/flow/testing/mock_texture_unittests.cc @@ -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(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(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); } diff --git a/impeller/renderer/backend/metal/texture_mtl.h b/impeller/renderer/backend/metal/texture_mtl.h index ef61433449119..9b6170e76e83d 100644 --- a/impeller/renderer/backend/metal/texture_mtl.h +++ b/impeller/renderer/backend/metal/texture_mtl.h @@ -15,16 +15,23 @@ namespace impeller { class TextureMTL final : public Texture, public BackendCast { public: - TextureMTL(TextureDescriptor desc, id texture); + TextureMTL(TextureDescriptor desc, + id texture, + bool wrapped = false); + + static TextureMTL Wrapper(TextureDescriptor desc, id texture); // |Texture| ~TextureMTL() override; id GetMTLTexture() const; + bool IsWrapped() const; + private: id texture_ = nullptr; bool is_valid_ = false; + bool is_wrapped_ = false; // |Texture| void SetLabel(std::string_view label) override; diff --git a/impeller/renderer/backend/metal/texture_mtl.mm b/impeller/renderer/backend/metal/texture_mtl.mm index c220a2967acde..8c295ab65d878 100644 --- a/impeller/renderer/backend/metal/texture_mtl.mm +++ b/impeller/renderer/backend/metal/texture_mtl.mm @@ -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 texture) +TextureMTL::TextureMTL(TextureDescriptor p_desc, + id texture, + bool wrapped) : Texture(p_desc), texture_(texture) { const auto& desc = GetTextureDescriptor(); @@ -21,9 +24,14 @@ return; } + is_wrapped_ = wrapped; is_valid_ = true; } +TextureMTL TextureMTL::Wrapper(TextureDescriptor desc, id texture) { + return TextureMTL(desc, texture, true); +} + TextureMTL::~TextureMTL() = default; void TextureMTL::SetLabel(std::string_view label) { @@ -42,7 +50,7 @@ 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 +91,8 @@ return is_valid_; } +bool TextureMTL::IsWrapped() const { + return is_wrapped_; +} + } // namespace impeller diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 1780a9b7d53e0..9589f0874aefa 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -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 {} diff --git a/shell/platform/android/android_external_texture_gl.cc b/shell/platform/android/android_external_texture_gl.cc index 599d6190b3306..a39ec83cc06e9 100644 --- a/shell/platform/android/android_external_texture_gl.cc +++ b/shell/platform/android/android_external_texture_gl.cc @@ -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 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 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); } } } diff --git a/shell/platform/android/android_external_texture_gl.h b/shell/platform/android/android_external_texture_gl.h index c9fc07fe6908f..b2cc8d75f85f8 100644 --- a/shell/platform/android/android_external_texture_gl.h +++ b/shell/platform/android/android_external_texture_gl.h @@ -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; diff --git a/shell/platform/darwin/ios/ios_external_texture_metal.h b/shell/platform/darwin/ios/ios_external_texture_metal.h index 158497d336329..ba0153013a907 100644 --- a/shell/platform/darwin/ios/ios_external_texture_metal.h +++ b/shell/platform/darwin/ios/ios_external_texture_metal.h @@ -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; diff --git a/shell/platform/darwin/ios/ios_external_texture_metal.mm b/shell/platform/darwin/ios/ios_external_texture_metal.mm index 50d1405a084bf..14d4ab91336f8 100644 --- a/shell/platform/darwin/ios/ios_external_texture_metal.mm +++ b/shell/platform/darwin/ios/ios_external_texture_metal.mm @@ -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,16 @@ 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 + const SkSamplingOptions& sampling) { + [darwin_external_texture_metal_ canvas:*context.canvas bounds:bounds freeze:freeze - grContext:context + grContext:context.gr_context sampling:sampling - paint:paint]; + paint:context.sk_paint]; } void IOSExternalTextureMetal::OnGrContextCreated() { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm index 144d09e22aad2..305fcb88800b0 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm @@ -111,7 +111,11 @@ - (CVPixelBufferRef)pixelBuffer { std::make_unique(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); @@ -161,7 +165,11 @@ - (CVPixelBufferRef)pixelBuffer { std::make_unique(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(); } @@ -209,7 +217,11 @@ - (CVPixelBufferRef)pixelBuffer { std::make_unique(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(); } @@ -257,7 +269,11 @@ - (CVPixelBufferRef)pixelBuffer { std::make_unique(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(); } diff --git a/shell/platform/embedder/embedder_external_texture_gl.cc b/shell/platform/embedder/embedder_external_texture_gl.cc index 94246797f5175..2454ce8782ba4 100644 --- a/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/shell/platform/embedder/embedder_external_texture_gl.cc @@ -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); diff --git a/shell/platform/embedder/embedder_external_texture_gl.h b/shell/platform/embedder/embedder_external_texture_gl.h index 887a0e50fe026..6d5585f352493 100644 --- a/shell/platform/embedder/embedder_external_texture_gl.h +++ b/shell/platform/embedder/embedder_external_texture_gl.h @@ -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; diff --git a/shell/platform/embedder/embedder_external_texture_metal.h b/shell/platform/embedder/embedder_external_texture_metal.h index 0587aa0f69ec5..6aa0908aeda75 100644 --- a/shell/platform/embedder/embedder_external_texture_metal.h +++ b/shell/platform/embedder/embedder_external_texture_metal.h @@ -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; diff --git a/shell/platform/embedder/embedder_external_texture_metal.mm b/shell/platform/embedder/embedder_external_texture_metal.mm index 4c880dc8b8aba..10ea81bda6cb4 100644 --- a/shell/platform/embedder/embedder_external_texture_metal.mm +++ b/shell/platform/embedder/embedder_external_texture_metal.mm @@ -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 @@ static bool ValidNumTextures(int expected, int actual) { 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); diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 08f653495f379..a7018859d1d47 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -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); } diff --git a/shell/platform/embedder/tests/embedder_unittests_metal.mm b/shell/platform/embedder/tests/embedder_unittests_metal.mm index 8e2bbf948bbdb..fd221fc736609 100644 --- a/shell/platform/embedder/tests/embedder_unittests_metal.mm +++ b/shell/platform/embedder/tests/embedder_unittests_metal.mm @@ -465,20 +465,24 @@ void Collect() { 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); From 376fe85bfe3a1096d52c7a95d12888c1b03acd3b Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Thu, 29 Sep 2022 18:31:03 +0800 Subject: [PATCH 2/7] Support external textures for iOS --- ci/licenses_golden/licenses_flutter | 2 + flow/layers/texture_layer.cc | 12 +- .../display_list/display_list_dispatcher.cc | 2 +- impeller/renderer/backend/metal/texture_mtl.h | 3 +- .../renderer/backend/metal/texture_mtl.mm | 5 +- impeller/renderer/texture.cc | 4 + impeller/renderer/texture.h | 4 +- shell/platform/darwin/graphics/BUILD.gn | 10 ++ .../graphics/FlutterDarwinContextMetal.mm | 3 +- .../FlutterDarwinContextMetalImpeller.h | 54 ++++++++ .../FlutterDarwinContextMetalImpeller.mm | 73 +++++++++++ .../FlutterDarwinExternalTextureMetal.h | 16 +-- .../FlutterDarwinExternalTextureMetal.mm | 124 +++++++++++++----- .../darwin/ios/ios_context_metal_impeller.h | 3 +- .../darwin/ios/ios_context_metal_impeller.mm | 28 ++-- .../darwin/ios/ios_external_texture_metal.mm | 10 +- 16 files changed, 272 insertions(+), 81 deletions(-) create mode 100644 shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h create mode 100644 shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 5d167e125da85..90004845adb5d 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1794,6 +1794,8 @@ FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/flutter_cod 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/FlutterDarwinExternalTextureMetal.h FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/Flutter.h diff --git a/flow/layers/texture_layer.cc b/flow/layers/texture_layer.cc index f9c95d7f025ee..8a98366f2c254 100644 --- a/flow/layers/texture_layer.cc +++ b/flow/layers/texture_layer.cc @@ -62,11 +62,13 @@ void TextureLayer::Paint(PaintContext& context) const { return; } AutoCachePaint cache_paint(context); - 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::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_)); } diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index ad2eb4286d123..d01cd360f87c7 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -1053,7 +1053,7 @@ void DisplayListDispatcher::drawImageRect( std::make_shared(image->impeller_texture()), // image ToRect(src), // source rect ToRect(dst), // destination rect - paint_, // paint + render_with_attributes ? paint_ : Paint(), // paint ToSamplerDescriptor(sampling) // sampling ); } diff --git a/impeller/renderer/backend/metal/texture_mtl.h b/impeller/renderer/backend/metal/texture_mtl.h index 9b6170e76e83d..1aedbeacaa6af 100644 --- a/impeller/renderer/backend/metal/texture_mtl.h +++ b/impeller/renderer/backend/metal/texture_mtl.h @@ -19,7 +19,8 @@ class TextureMTL final : public Texture, id texture, bool wrapped = false); - static TextureMTL Wrapper(TextureDescriptor desc, id texture); + static std::shared_ptr Wrapper(TextureDescriptor desc, + id texture); // |Texture| ~TextureMTL() override; diff --git a/impeller/renderer/backend/metal/texture_mtl.mm b/impeller/renderer/backend/metal/texture_mtl.mm index 8c295ab65d878..6877c1b871ac9 100644 --- a/impeller/renderer/backend/metal/texture_mtl.mm +++ b/impeller/renderer/backend/metal/texture_mtl.mm @@ -28,8 +28,9 @@ is_valid_ = true; } -TextureMTL TextureMTL::Wrapper(TextureDescriptor desc, id texture) { - return TextureMTL(desc, texture, true); +std::shared_ptr TextureMTL::Wrapper(TextureDescriptor desc, + id texture) { + return std::make_shared(desc, texture, true); } TextureMTL::~TextureMTL() = default; diff --git a/impeller/renderer/texture.cc b/impeller/renderer/texture.cc index a2c2079936713..64860c181a038 100644 --- a/impeller/renderer/texture.cc +++ b/impeller/renderer/texture.cc @@ -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_; } diff --git a/impeller/renderer/texture.h b/impeller/renderer/texture.h index df51d7daf9628..8ac7b7b0d1fa9 100644 --- a/impeller/renderer/texture.h +++ b/impeller/renderer/texture.h @@ -35,6 +35,8 @@ class Texture { const TextureDescriptor& GetTextureDescriptor() const; + void SetIntent(TextureIntent intent); + TextureIntent GetIntent() const; virtual Scalar GetYCoordScale() const; @@ -51,7 +53,7 @@ class Texture { size_t slice) = 0; private: - TextureIntent intent_ = TextureIntent::kRenderToTexture; + TextureIntent intent_ = TextureIntent::kUploadFromHost; const TextureDescriptor desc_; bool IsSliceValid(size_t slice) const; diff --git a/shell/platform/darwin/graphics/BUILD.gn b/shell/platform/darwin/graphics/BUILD.gn index c7c151c10d33f..636c02ff7473c 100644 --- a/shell/platform/darwin/graphics/BUILD.gn +++ b/shell/platform/darwin/graphics/BUILD.gn @@ -5,6 +5,7 @@ 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 @@ -19,11 +20,20 @@ source_set("graphics") { 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" ] diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm index 0cd3fe98906dc..52f4c466cf0b3 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm @@ -94,7 +94,8 @@ - (void)dealloc { texture:(NSObject*)texture { return [[FlutterDarwinExternalTextureMetal alloc] initWithTextureCache:_textureCache textureID:textureID - texture:texture]; + texture:texture + enableImpeller:NO]; } @end diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h new file mode 100644 index 0000000000000..ee7154a6dff2a --- /dev/null +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h @@ -0,0 +1,54 @@ +// 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 +#import +#import + +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h" +#import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h" +#include "flutter/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*)texture; + +/** + * MTLDevice that is backing this context.s + */ +@property(nonatomic, readonly) id device; + +/** + * Impeller context; +*/ +@property(nonatomic, readonly) std::shared_ptr context; + +/* + * Texture cache for external textures. + */ +@property(nonatomic, readonly) CVMetalTextureCacheRef textureCache; + +@end + +NS_ASSUME_NONNULL_END + +#endif // SHELL_PLATFORM_DARWIN_GRAPHICS_DARWIN_CONTEXT_METAL_IMPELLER_H_ diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm new file mode 100644 index 0000000000000..2be13f4dcc52b --- /dev/null +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm @@ -0,0 +1,73 @@ +// 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/shell/common/context_options.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" +#include "flutter/impeller/entity/mtl/entity_shaders.h" +#include "flutter/impeller/renderer/backend/metal/context_mtl.h" + +FLUTTER_ASSERT_ARC + +static std::shared_ptr CreateImpellerContext() { + std::vector> shader_mappings = { + std::make_shared(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(); + _device = impeller::ContextMTL::Cast(*_context).GetMTLDevice(); + + if (!_device) { + FML_DLOG(ERROR) << "Could not acquire Metal device."; + return nil; + } + + 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; + } + } + return self; +} + +- (void)dealloc { + if (_textureCache) { + CFRelease(_textureCache); + } +} + +- (FlutterDarwinExternalTextureMetal*) + createExternalTextureWithIdentifier:(int64_t)textureID + texture:(NSObject*)texture { + return [[FlutterDarwinExternalTextureMetal alloc] initWithTextureCache:_textureCache + textureID:textureID + texture:texture + enableImpeller:YES]; +} + +@end diff --git a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h index 042aec510abd8..c3c495870c9ec 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h +++ b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h @@ -5,6 +5,7 @@ #import #import +#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" @@ -28,14 +29,13 @@ - (nullable instancetype)initWithTextureCache:(nonnull CVMetalTextureCacheRef)textureCache textureID:(int64_t)textureID - texture:(nonnull NSObject*)texture; - -- (void)canvas:(SkCanvas&)canvas - bounds:(const SkRect&)bounds - freeze:(BOOL)freeze - grContext:(nonnull GrDirectContext*)grContext - sampling:(const SkSamplingOptions&)sampling - paint:(nullable const SkPaint*)paint; + texture:(nonnull NSObject*)texture + enableImpeller:(BOOL)enableImpeller; + +- (void)paintContext:(flutter::Texture::PaintContext&)context + bounds:(const SkRect&)bounds + freeze:(BOOL)freeze + sampling:(const SkSamplingOptions&)sampling; - (void)onGrContextCreated; diff --git a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm index 6af2b62bdba74..32117058b5589 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm @@ -3,6 +3,13 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h" +#include "flutter/display_list/display_list_image.h" + +#if IMPELLER_SUPPORTS_RENDERING +#include "impeller/base/config.h" +#include "impeller/display_list/display_list_image_impeller.h" +#include "impeller/renderer/backend/metal/texture_mtl.h" +#endif // IMPELLER_SUPPORTS_RENDERING #include "flutter/fml/logging.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" @@ -19,19 +26,22 @@ @implementation FlutterDarwinExternalTextureMetal { CVMetalTextureCacheRef _textureCache; NSObject* _externalTexture; BOOL _textureFrameAvailable; - sk_sp _externalImage; + sk_sp _externalImage; CVPixelBufferRef _lastPixelBuffer; OSType _pixelFormat; + BOOL _enableImpeller; } - (instancetype)initWithTextureCache:(nonnull CVMetalTextureCacheRef)textureCache textureID:(int64_t)textureID - texture:(NSObject*)texture { + texture:(NSObject*)texture + enableImpeller:(BOOL)enableImpeller { if (self = [super init]) { _textureCache = textureCache; CFRetain(_textureCache); _textureID = textureID; _externalTexture = texture; + _enableImpeller = enableImpeller; return self; } return nil; @@ -47,30 +57,43 @@ - (void)dealloc { } } -- (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 IMPELLER_SUPPORTS_RENDERING + if (_enableImpeller) { + context.builder->drawImageRect( + _externalImage, // image + SkRect::Make(_externalImage->bounds()), // source rect + bounds, // destination rect + flutter::ToDl(sampling), // sampling + context.dl_paint, + SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint // constraint + ); + return; + } +#endif // IMPELLER_SUPPORTS_RENDERING + + 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 +103,7 @@ - (void)onNeedsUpdatedTexture:(nonnull GrDirectContext*)grContext { // 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 image = [self wrapExternalPixelBuffer:_lastPixelBuffer grContext:grContext]; + sk_sp image = [self wrapExternalPixelBuffer:_lastPixelBuffer context:context]; if (image) { _externalImage = image; _textureFrameAvailable = false; @@ -116,29 +139,36 @@ - (void)onTextureUnregistered { #pragma mark - External texture skia wrapper methods. -- (sk_sp)wrapExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer - grContext:(GrDirectContext*)grContext { +- (sk_sp)wrapExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer + context:(flutter::Texture::PaintContext&)context { if (!pixelBuffer) { return nullptr; } - sk_sp image = nullptr; + sk_sp 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)wrapNV12ExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer - grContext:(GrDirectContext*)grContext { +- (sk_sp)wrapNV12ExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer + context:(flutter::Texture::PaintContext&)context { +#if IMPELLER_SUPPORTS_RENDERING + if (_enableImpeller) { + IMPELLER_UNIMPLEMENTED + return nullptr; + } +#endif // IMPELLER_SUPPORTS_RENDERING + SkISize textureSize = SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer)); CVMetalTextureRef yMetalTexture = nullptr; @@ -185,15 +215,20 @@ - (void)onTextureUnregistered { id uvTex = CVMetalTextureGetTexture(uvMetalTexture); CVBufferRelease(uvMetalTexture); - return [FlutterDarwinExternalTextureSkImageWrapper wrapYUVATexture:yTex - UVTex:uvTex - grContext:grContext - width:textureSize.width() - height:textureSize.height()]; + auto skImage = [FlutterDarwinExternalTextureSkImageWrapper wrapYUVATexture:yTex + UVTex:uvTex + grContext:context.gr_context + width:textureSize.width() + height:textureSize.height()]; + if (!skImage) { + return nullptr; + } + + return flutter::DlImage::Make(skImage); } -- (sk_sp)wrapRGBAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer - grContext:(GrDirectContext*)grContext { +- (sk_sp)wrapRGBAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer + context:(flutter::Texture::PaintContext&)context { SkISize textureSize = SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer)); CVMetalTextureRef metalTexture = nullptr; @@ -216,10 +251,27 @@ - (void)onTextureUnregistered { id rgbaTex = CVMetalTextureGetTexture(metalTexture); CVBufferRelease(metalTexture); - return [FlutterDarwinExternalTextureSkImageWrapper wrapRGBATexture:rgbaTex - grContext:grContext - width:textureSize.width() - height:textureSize.height()]; +#if IMPELLER_SUPPORTS_RENDERING + 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); + } +#endif // IMPELLER_SUPPORTS_RENDERING + + 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 diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.h b/shell/platform/darwin/ios/ios_context_metal_impeller.h index 4e3dca13e55e8..6efb530728de9 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.h +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.h @@ -7,6 +7,7 @@ #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/ios/ios_context.h" namespace impeller { @@ -33,7 +34,7 @@ class IOSContextMetalImpeller final : public IOSContext { sk_sp GetResourceContext() const; private: - std::shared_ptr context_; + fml::scoped_nsobject darwin_context_metal_impeller_; // |IOSContext| sk_sp CreateResourceContext() override; diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.mm b/shell/platform/darwin/ios/ios_context_metal_impeller.mm index 6747c522c0f2f..0ad9659fc94e3 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.mm @@ -3,28 +3,15 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h" - +#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h" #include "flutter/impeller/entity/mtl/entity_shaders.h" -#include "flutter/impeller/renderer/backend/metal/context_mtl.h" namespace flutter { -static std::shared_ptr CreateImpellerContext() { - std::vector> shader_mappings = { - std::make_shared(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 alloc] init]}) {} IOSContextMetalImpeller::~IOSContextMetalImpeller() = default; @@ -51,7 +38,7 @@ // |IOSContext| std::shared_ptr IOSContextMetalImpeller::GetImpellerContext() const { - return context_; + return darwin_context_metal_impeller_.get().context; } // |IOSContext| @@ -64,7 +51,10 @@ std::unique_ptr IOSContextMetalImpeller::CreateExternalTexture( int64_t texture_id, fml::scoped_nsobject> texture) { - return nullptr; + return std::make_unique( + fml::scoped_nsobject{ + [[darwin_context_metal_impeller_ createExternalTextureWithIdentifier:texture_id + texture:texture] retain]}); } } // namespace flutter diff --git a/shell/platform/darwin/ios/ios_external_texture_metal.mm b/shell/platform/darwin/ios/ios_external_texture_metal.mm index 14d4ab91336f8..ccc68aa07a008 100644 --- a/shell/platform/darwin/ios/ios_external_texture_metal.mm +++ b/shell/platform/darwin/ios/ios_external_texture_metal.mm @@ -18,12 +18,10 @@ const SkRect& bounds, bool freeze, const SkSamplingOptions& sampling) { - [darwin_external_texture_metal_ canvas:*context.canvas - bounds:bounds - freeze:freeze - grContext:context.gr_context - sampling:sampling - paint:context.sk_paint]; + [darwin_external_texture_metal_ paintContext:context + bounds:bounds + freeze:freeze + sampling:sampling]; } void IOSExternalTextureMetal::OnGrContextCreated() { From 94b881d430120b3ce0a3e6f0414a503611957493 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Thu, 29 Sep 2022 18:31:47 +0800 Subject: [PATCH 3/7] format code --- .../darwin/graphics/FlutterDarwinContextMetalImpeller.h | 4 ++-- .../darwin/graphics/FlutterDarwinContextMetalImpeller.mm | 6 +++--- shell/platform/darwin/ios/ios_context_metal_impeller.mm | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h index ee7154a6dff2a..ea56856817fbe 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h @@ -9,9 +9,9 @@ #import #import +#include "flutter/impeller/renderer/backend/metal/context_mtl.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h" #import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h" -#include "flutter/impeller/renderer/backend/metal/context_mtl.h" NS_ASSUME_NONNULL_BEGIN @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Impeller context; -*/ + */ @property(nonatomic, readonly) std::shared_ptr context; /* diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm index 2be13f4dcc52b..43e1be235d909 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm @@ -6,10 +6,10 @@ #include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/logging.h" -#include "flutter/shell/common/context_options.h" -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.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 @@ -24,7 +24,7 @@ return nullptr; } FML_LOG(ERROR) << "Using the Impeller rendering backend."; - + return context; } diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.mm b/shell/platform/darwin/ios/ios_context_metal_impeller.mm index 0ad9659fc94e3..bab3c96129984 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.mm @@ -3,8 +3,8 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h" -#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h" #include "flutter/impeller/entity/mtl/entity_shaders.h" +#import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h" namespace flutter { From 1cfeaa78ded46f1fc2076da8e75e4bf85c485940 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Thu, 29 Sep 2022 21:48:11 +0800 Subject: [PATCH 4/7] Tweak code --- ci/licenses_golden/licenses_flutter | 4 ++-- shell/common/shell_test_platform_view_metal.mm | 8 ++++---- .../android/android_external_texture_gl.cc | 14 +++++++------- shell/platform/darwin/graphics/BUILD.gn | 4 ++-- ...Metal.h => FlutterDarwinContextMetalSkia.h} | 6 +++--- ...tal.mm => FlutterDarwinContextMetalSkia.mm} | 6 +++--- .../darwin/ios/ios_context_metal_impeller.h | 4 ++-- .../darwin/ios/ios_context_metal_impeller.mm | 5 +++-- .../darwin/ios/ios_context_metal_skia.h | 6 +++--- .../darwin/ios/ios_context_metal_skia.mm | 8 ++++---- .../FlutterEmbedderExternalTextureUnittests.mm | 18 +++++++++--------- .../Source/FlutterExternalTextureMetal.h | 4 ++-- .../Source/FlutterExternalTextureMetal.mm | 4 ++-- .../framework/Source/FlutterMetalRenderer.mm | 6 +++--- .../embedder/embedder_surface_metal.mm | 11 ++++++----- 15 files changed, 55 insertions(+), 53 deletions(-) rename shell/platform/darwin/graphics/{FlutterDarwinContextMetal.h => FlutterDarwinContextMetalSkia.h} (90%) rename shell/platform/darwin/graphics/{FlutterDarwinContextMetal.mm => FlutterDarwinContextMetalSkia.mm} (95%) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 90004845adb5d..b83e91ef8d37d 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1792,8 +1792,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/graphics/FlutterDarwinContextMetalSkia.h +FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.mm FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 42794260749d1..814e67e6f3933 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -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 @@ class DarwinContextMetal { public: DarwinContextMetal() - : context_([[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice]), + : context_([[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]), offscreen_texture_(CreateOffscreenTexture([context_.get() device])) {} ~DarwinContextMetal() = default; - fml::scoped_nsobject context() const { return context_; } + fml::scoped_nsobject context() const { return context_; } fml::scoped_nsprotocol> offscreen_texture() const { return offscreen_texture_; } @@ -47,7 +47,7 @@ GPUMTLTextureInfo offscreen_texture_info() const { } private: - const fml::scoped_nsobject context_; + const fml::scoped_nsobject context_; const fml::scoped_nsprotocol> offscreen_texture_; FML_DISALLOW_COPY_AND_ASSIGN(DarwinContextMetal); diff --git a/shell/platform/android/android_external_texture_gl.cc b/shell/platform/android/android_external_texture_gl.cc index a39ec83cc06e9..2a58de3a96171 100644 --- a/shell/platform/android/android_external_texture_gl.cc +++ b/shell/platform/android/android_external_texture_gl.cc @@ -61,26 +61,26 @@ void AndroidExternalTextureGL::Paint(PaintContext& context, context.gr_context, backendTexture, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr); if (image) { - SkAutoCanvasRestore autoRestore(context->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. - context->canvas->translate(bounds.x(), bounds.y() + bounds.height()); - context->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 shader = image->makeShader( SkTileMode::kRepeat, SkTileMode::kRepeat, sampling, transform); SkPaint paintWithShader; - if (context->sk_paint) { - paintWithShader = *context->sk_paint; + if (context.sk_paint) { + paintWithShader = *context.sk_paint; } paintWithShader.setShader(shader); - context->canvas->drawRect(SkRect::MakeWH(1, 1), paintWithShader); + context.canvas->drawRect(SkRect::MakeWH(1, 1), paintWithShader); } else { - context->canvas->drawImage(image, 0, 0, sampling, context->sk_paint); + context.canvas->drawImage(image, 0, 0, sampling, context.sk_paint); } } } diff --git a/shell/platform/darwin/graphics/BUILD.gn b/shell/platform/darwin/graphics/BUILD.gn index 636c02ff7473c..fbb5a7a5b1035 100644 --- a/shell/platform/darwin/graphics/BUILD.gn +++ b/shell/platform/darwin/graphics/BUILD.gn @@ -12,8 +12,8 @@ source_set("graphics") { cflags_objcc = flutter_cflags_objcc_arc sources = [ - "FlutterDarwinContextMetal.h", - "FlutterDarwinContextMetal.mm", + "FlutterDarwinContextMetalSkia.h", + "FlutterDarwinContextMetalSkia.mm", "FlutterDarwinExternalTextureMetal.h", "FlutterDarwinExternalTextureMetal.mm", ] diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h b/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h similarity index 90% rename from shell/platform/darwin/graphics/FlutterDarwinContextMetal.h rename to shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h index 2c93aff87f8c2..02eb2197332fe 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.h +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h @@ -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)device commandQueue:(id)commandQueue; diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.mm similarity index 95% rename from shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm rename to shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.mm index 52f4c466cf0b3..c6e1321b19f8c 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.mm @@ -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 device = MTLCreateSystemDefaultDevice(); @@ -70,7 +70,7 @@ - (instancetype)initWithMTLDevice:(id)device flutter::MakeDefaultContextOptions(flutter::ContextType::kRender, GrBackendApi::kMetal); id device = _device; id commandQueue = _commandQueue; - return [FlutterDarwinContextMetal createGrContext:device commandQueue:commandQueue]; + return [FlutterDarwinContextMetalSkia createGrContext:device commandQueue:commandQueue]; } + (sk_sp)createGrContext:(id)device diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.h b/shell/platform/darwin/ios/ios_context_metal_impeller.h index 6efb530728de9..a46dc81cfed9c 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.h +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.h @@ -6,8 +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 { @@ -24,7 +24,7 @@ class IOSContextMetalImpeller final : public IOSContext { ~IOSContextMetalImpeller(); - fml::scoped_nsobject GetDarwinContext() const; + fml::scoped_nsobject GetDarwinContext() const; IOSRenderingBackend GetBackend() const override; diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.mm b/shell/platform/darwin/ios/ios_context_metal_impeller.mm index bab3c96129984..fc011f652c4cf 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.mm @@ -15,8 +15,9 @@ IOSContextMetalImpeller::~IOSContextMetalImpeller() = default; -fml::scoped_nsobject IOSContextMetalImpeller::GetDarwinContext() const { - return fml::scoped_nsobject{}; +fml::scoped_nsobject IOSContextMetalImpeller::GetDarwinContext() + const { + return fml::scoped_nsobject{}; } IOSRenderingBackend IOSContextMetalImpeller::GetBackend() const { diff --git a/shell/platform/darwin/ios/ios_context_metal_skia.h b/shell/platform/darwin/ios/ios_context_metal_skia.h index 48661f7d18edb..42b6a8285f64b 100644 --- a/shell/platform/darwin/ios/ios_context_metal_skia.h +++ b/shell/platform/darwin/ios/ios_context_metal_skia.h @@ -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 GetDarwinContext() const; + fml::scoped_nsobject GetDarwinContext() const; // |IOSContext| IOSRenderingBackend GetBackend() const override; @@ -33,7 +33,7 @@ class IOSContextMetalSkia final : public IOSContext { sk_sp GetResourceContext() const; private: - fml::scoped_nsobject darwin_context_metal_; + fml::scoped_nsobject darwin_context_metal_; // |IOSContext| sk_sp CreateResourceContext() override; diff --git a/shell/platform/darwin/ios/ios_context_metal_skia.mm b/shell/platform/darwin/ios/ios_context_metal_skia.mm index fb4ef48762237..1a4d8c8ed358e 100644 --- a/shell/platform/darwin/ios/ios_context_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_context_metal_skia.mm @@ -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 alloc] initWithDefaultMTLDevice]}; + darwin_context_metal_ = fml::scoped_nsobject{ + [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]}; } IOSContextMetalSkia::~IOSContextMetalSkia() = default; -fml::scoped_nsobject IOSContextMetalSkia::GetDarwinContext() const { +fml::scoped_nsobject IOSContextMetalSkia::GetDarwinContext() const { return darwin_context_metal_; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm index 305fcb88800b0..ed2032120f868 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm @@ -8,7 +8,7 @@ #include #include -#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 @@ - (CVPixelBufferRef)pixelBuffer { 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 gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info)); @@ -129,8 +129,8 @@ - (CVPixelBufferRef)pixelBuffer { 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 gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info)); @@ -181,8 +181,8 @@ - (CVPixelBufferRef)pixelBuffer { 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 gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info)); @@ -233,8 +233,8 @@ - (CVPixelBufferRef)pixelBuffer { 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 gpuSurface(SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info)); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h b/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h index df0db4b1dd95f..8942d1ff71062 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h @@ -4,7 +4,7 @@ #import -#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)texture - darwinMetalContext:(nonnull FlutterDarwinContextMetal*)context; + darwinMetalContext:(nonnull FlutterDarwinContextMetalSkia*)context; /** * Accepts texture buffer copy request from the Flutter engine. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm b/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm index 1ece011425d3c..6ca826d704f6d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm @@ -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 @@ @implementation FlutterExternalTextureMetal { } - (instancetype)initWithFlutterTexture:(id)texture - darwinMetalContext:(FlutterDarwinContextMetal*)context { + darwinMetalContext:(FlutterDarwinContextMetalSkia*)context { self = [super init]; if (self) { _texture = texture; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.mm b/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.mm index 2347d06fa098a..c5305c683baa2 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.mm @@ -40,7 +40,7 @@ @implementation FlutterMetalRenderer { FlutterView* _flutterView; - FlutterDarwinContextMetal* _darwinMetalContext; + FlutterDarwinContextMetalSkia* _darwinMetalContext; } - (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine { @@ -60,8 +60,8 @@ - (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine { return nil; } - _darwinMetalContext = [[FlutterDarwinContextMetal alloc] initWithMTLDevice:_device - commandQueue:_commandQueue]; + _darwinMetalContext = [[FlutterDarwinContextMetalSkia alloc] initWithMTLDevice:_device + commandQueue:_commandQueue]; } return self; } diff --git a/shell/platform/embedder/embedder_surface_metal.mm b/shell/platform/embedder/embedder_surface_metal.mm index afa11d62f610b..b7582d01b5c2c 100644 --- a/shell/platform/embedder/embedder_surface_metal.mm +++ b/shell/platform/embedder/embedder_surface_metal.mm @@ -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 @@ : GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture), metal_dispatch_table_(std::move(metal_dispatch_table)), external_view_embedder_(std::move(external_view_embedder)) { - main_context_ = [FlutterDarwinContextMetal createGrContext:(id)device - commandQueue:(id)command_queue]; + main_context_ = + [FlutterDarwinContextMetalSkia createGrContext:(id)device + commandQueue:(id)command_queue]; resource_context_ = - [FlutterDarwinContextMetal createGrContext:(id)device - commandQueue:(id)command_queue]; + [FlutterDarwinContextMetalSkia createGrContext:(id)device + commandQueue:(id)command_queue]; valid_ = main_context_ && resource_context_; } From 134cd0cc4f964b0797f413eeaceb21452900db9a Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Fri, 30 Sep 2022 22:20:55 +0800 Subject: [PATCH 5/7] format --- ci/licenses_golden/licenses_flutter | 4 ++-- .../graphics/FlutterDarwinExternalTextureMetal.mm | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index b83e91ef8d37d..baeaec8768873 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1792,10 +1792,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/FlutterDarwinContextMetalSkia.h -FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.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 diff --git a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm index 32117058b5589..8b31da85f6b55 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm @@ -71,11 +71,11 @@ - (void)paintContext:(flutter::Texture::PaintContext&)context #if IMPELLER_SUPPORTS_RENDERING if (_enableImpeller) { context.builder->drawImageRect( - _externalImage, // image - SkRect::Make(_externalImage->bounds()), // source rect - bounds, // destination rect - flutter::ToDl(sampling), // sampling - context.dl_paint, + _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; From 440769f94e601069df20e03c01b88708ad2fbadd Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Fri, 7 Oct 2022 09:10:44 +0800 Subject: [PATCH 6/7] Clean code --- common/graphics/texture.h | 1 - impeller/renderer/texture.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/common/graphics/texture.h b/common/graphics/texture.h index da17bfadeeca1..585b3c14bb12d 100644 --- a/common/graphics/texture.h +++ b/common/graphics/texture.h @@ -41,7 +41,6 @@ class Texture : public ContextListener { GrDirectContext* gr_context = nullptr; const SkPaint* sk_paint = nullptr; const DlPaint* dl_paint = nullptr; - bool enable_impeller = false; }; explicit Texture(int64_t id); // Called from UI or raster thread. diff --git a/impeller/renderer/texture.h b/impeller/renderer/texture.h index 8ac7b7b0d1fa9..4491e06f859e9 100644 --- a/impeller/renderer/texture.h +++ b/impeller/renderer/texture.h @@ -53,7 +53,7 @@ class Texture { size_t slice) = 0; private: - TextureIntent intent_ = TextureIntent::kUploadFromHost; + TextureIntent intent_ = TextureIntent::kRenderToTexture; const TextureDescriptor desc_; bool IsSliceValid(size_t slice) const; From 3bf8390e9d8bf6506c5f595e41c5f03b8e11c014 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Wed, 19 Oct 2022 19:34:48 +0800 Subject: [PATCH 7/7] Clean code --- impeller/renderer/backend/metal/context_mtl.h | 4 ++-- .../renderer/backend/metal/context_mtl.mm | 4 ++-- .../FlutterDarwinContextMetalImpeller.h | 13 ++++------ .../FlutterDarwinContextMetalImpeller.mm | 24 ++++++++----------- .../FlutterDarwinExternalTextureMetal.mm | 17 +++---------- 5 files changed, 21 insertions(+), 41 deletions(-) diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index 98f6c9139a118..779896f2b03e0 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -23,10 +23,10 @@ namespace impeller { class ContextMTL final : public Context, public BackendCast { public: - static std::shared_ptr Create( + static std::shared_ptr Create( const std::vector& shader_library_paths); - static std::shared_ptr Create( + static std::shared_ptr Create( const std::vector>& shader_libraries_data, const std::string& label); diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index 8cc908a8d06f8..f1cbc2acf5b49 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -152,7 +152,7 @@ return ::MTLCreateSystemDefaultDevice(); } -std::shared_ptr ContextMTL::Create( +std::shared_ptr ContextMTL::Create( const std::vector& shader_library_paths) { auto device = CreateMetalDevice(); auto context = std::shared_ptr(new ContextMTL( @@ -164,7 +164,7 @@ return context; } -std::shared_ptr ContextMTL::Create( +std::shared_ptr ContextMTL::Create( const std::vector>& shader_libraries_data, const std::string& label) { auto device = CreateMetalDevice(); diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h index ea56856817fbe..f705a4f9a4c57 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h @@ -9,9 +9,10 @@ #import #import -#include "flutter/impeller/renderer/backend/metal/context_mtl.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 @@ -31,21 +32,15 @@ NS_ASSUME_NONNULL_BEGIN - (FlutterDarwinExternalTextureMetal*) createExternalTextureWithIdentifier:(int64_t)textureID texture:(NSObject*)texture; - -/** - * MTLDevice that is backing this context.s - */ -@property(nonatomic, readonly) id device; - /** * Impeller context; */ -@property(nonatomic, readonly) std::shared_ptr context; +@property(nonatomic, readonly) std::shared_ptr context; /* * Texture cache for external textures. */ -@property(nonatomic, readonly) CVMetalTextureCacheRef textureCache; +@property(nonatomic, readonly) fml::CFRef textureCache; @end diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm index 43e1be235d909..a75711c2b4441 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm @@ -13,7 +13,7 @@ FLUTTER_ASSERT_ARC -static std::shared_ptr CreateImpellerContext() { +static std::shared_ptr CreateImpellerContext() { std::vector> shader_mappings = { std::make_shared(impeller_entity_shaders_data, impeller_entity_shaders_length), @@ -34,33 +34,29 @@ - (instancetype)init { self = [super init]; if (self != nil) { _context = CreateImpellerContext(); - _device = impeller::ContextMTL::Cast(*_context).GetMTLDevice(); - - if (!_device) { + id 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 + 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; } -- (void)dealloc { - if (_textureCache) { - CFRelease(_textureCache); - } -} - - (FlutterDarwinExternalTextureMetal*) createExternalTextureWithIdentifier:(int64_t)textureID texture:(NSObject*)texture { diff --git a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm index 53b4dbd037576..42d4d3d9c1dff 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm @@ -4,15 +4,9 @@ #import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h" #include "flutter/display_list/display_list_image.h" - -#if IMPELLER_SUPPORTS_RENDERING -#include "impeller/base/config.h" +#include "impeller/base/validation.h" #include "impeller/display_list/display_list_image_impeller.h" #include "impeller/renderer/backend/metal/texture_mtl.h" -#endif // IMPELLER_SUPPORTS_RENDERING - -#include "flutter/fml/logging.h" -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.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" @@ -68,7 +62,6 @@ - (void)paintContext:(flutter::Texture::PaintContext&)context } if (_externalImage) { -#if IMPELLER_SUPPORTS_RENDERING if (_enableImpeller) { context.builder->drawImageRect( _externalImage, // image @@ -80,7 +73,6 @@ - (void)paintContext:(flutter::Texture::PaintContext&)context ); return; } -#endif // IMPELLER_SUPPORTS_RENDERING context.canvas->drawImageRect( _externalImage->skia_image(), // image @@ -162,12 +154,11 @@ - (void)onTextureUnregistered { - (sk_sp)wrapNV12ExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer context:(flutter::Texture::PaintContext&)context { -#if IMPELLER_SUPPORTS_RENDERING if (_enableImpeller) { - IMPELLER_UNIMPLEMENTED + // TODO(113688): Support YUV external textures. + VALIDATION_LOG << "YUV external texture support is not implemented yet."; return nullptr; } -#endif // IMPELLER_SUPPORTS_RENDERING SkISize textureSize = SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer)); @@ -255,7 +246,6 @@ - (void)onTextureUnregistered { id rgbaTex = CVMetalTextureGetTexture(metalTexture); CVBufferRelease(metalTexture); -#if IMPELLER_SUPPORTS_RENDERING if (_enableImpeller) { impeller::TextureDescriptor desc; desc.storage_mode = impeller::StorageMode::kHostVisible; @@ -266,7 +256,6 @@ - (void)onTextureUnregistered { texture->SetIntent(impeller::TextureIntent::kUploadFromHost); return impeller::DlImageImpeller::Make(texture); } -#endif // IMPELLER_SUPPORTS_RENDERING auto skImage = [FlutterDarwinExternalTextureSkImageWrapper wrapRGBATexture:rgbaTex grContext:context.gr_context