5#define FML_USED_ON_EMBEDDER
10#import <Metal/Metal.h>
23#include "third_party/skia/include/core/SkSurface.h"
24#include "third_party/skia/include/gpu/GpuTypes.h"
25#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
26#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
27#include "third_party/skia/include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
28#include "third_party/skia/include/gpu/ganesh/mtl/GrMtlTypes.h"
36using EmbedderTest = testing::EmbedderTest;
39 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
45 auto rendered_scene = context.GetNextSceneImage();
48 ASSERT_TRUE(
engine.is_valid());
55 event.pixel_ratio = 1.0;
66 GrMtlTextureInfo info;
68 GrBackendTexture backend_texture = GrBackendTextures::MakeMtl(
69 texture_size.
width, texture_size.
height, skgpu::Mipmapped::kNo, info);
71 return SkSurfaces::WrapBackendTexture(skia_context.get(), backend_texture,
72 kTopLeft_GrSurfaceOrigin, 1, kBGRA_8888_SkColorType,
77 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
79 const auto texture_size =
DlISize(800, 600);
87 auto canvas =
surface->getCanvas();
88 canvas->clear(SK_ColorRED);
91 std::vector<FlutterMetalTextureHandle> textures{texture_info.
texture};
93 context.SetExternalTextureCallback(
95 EXPECT_TRUE(w == texture_size.width);
96 EXPECT_TRUE(
h == texture_size.height);
112 ASSERT_TRUE(
engine.is_valid());
116 auto rendered_scene = context.GetNextSceneImage();
121 event.width = texture_size.width;
122 event.height = texture_size.height;
123 event.pixel_ratio = 1.0;
130 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
140 context.GetCompositor().SetNextPresentCallback(
156 .rects = paint_region_rects,
160 .paint_region = &paint_region,
171 ASSERT_EQ(*
layers[0], layer);
186 ASSERT_EQ(*
layers[1], layer);
201 .rects = paint_region_rects,
205 .paint_region = &paint_region,
216 ASSERT_EQ(*
layers[2], layer);
222 context.AddNativeCallback(
233 event.pixel_ratio = 1.0;
235 ASSERT_TRUE(
engine.is_valid());
241 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
248 auto rendered_scene = context.GetNextSceneImage();
251 ASSERT_TRUE(
engine.is_valid());
258 event.pixel_ratio = 1.0;
265 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
269 builder.
SetDartEntrypoint(
"texture_destruction_callback_called_without_custom_compositor");
271 struct CollectContext {
272 int present_count = 0;
273 int collect_count = 0;
277 auto collect_context = std::make_unique<CollectContext>();
278 context.SetNextDrawableCallback([&context, &collect_context](
const FlutterFrameInfo* frame_info) {
279 auto texture_info = context.GetTestMetalSurface()->GetTextureInfo();
283 texture.texture_id = texture_info.texture_id;
285 texture.user_data = collect_context.get();
287 CollectContext* callback_collect_context =
reinterpret_cast<CollectContext*
>(
user_data);
288 ASSERT_TRUE(callback_collect_context->present_count > 0);
289 callback_collect_context->collect_count++;
290 callback_collect_context->latch.Signal();
294 context.SetPresentCallback([&context, &collect_context](int64_t
texture_id) {
295 collect_context->present_count++;
296 return context.GetTestMetalContext()->Present(
texture_id);
306 event.pixel_ratio = 1.0;
308 ASSERT_TRUE(
engine.is_valid());
310 collect_context->latch.Wait();
311 EXPECT_EQ(collect_context->collect_count, 1);
315 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
326 auto scene_image = context.GetNextSceneImage();
328 context.GetCompositor().SetNextPresentCallback(
344 .rects = paint_region_rects,
348 .paint_region = &paint_region,
359 ASSERT_EQ(*
layers[0], layer);
375 ASSERT_EQ(*
layers[1], layer);
390 .rects = paint_region_rects,
394 .paint_region = &paint_region,
405 ASSERT_EQ(*
layers[2], layer);
421 ASSERT_EQ(*
layers[3], layer);
436 .rects = paint_region_rects,
440 .paint_region = &paint_region,
451 ASSERT_EQ(*
layers[4], layer);
457 context.GetCompositor().SetPlatformViewRendererCallback(
458 [&](
const FlutterLayer& layer, GrDirectContext* context) -> sk_sp<SkImage> {
460 auto canvas =
surface->getCanvas();
467 paint.setColor(SK_ColorGREEN);
470 canvas->drawRect(rect, paint);
476 paint.setColor(SK_ColorMAGENTA);
479 canvas->drawRect(rect, paint);
484 FML_CHECK(
false) <<
"Test was asked to composite an unknown platform view.";
487 return surface->makeImageSnapshot();
490 context.AddNativeCallback(
502 event.pixel_ratio = 1.0;
504 ASSERT_TRUE(
engine.is_valid());
512 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
519 class TestCollectOnce {
523 ASSERT_FALSE(collected_);
528 bool collected_ =
false;
539 backing_store_out->user_data =
nullptr;
540 backing_store_out->metal.texture.texture = 0;
542 backing_store_out->metal.texture.user_data =
new TestCollectOnce();
543 backing_store_out->metal.texture.destruction_callback = [](
void*
user_data) {
544 reinterpret_cast<TestCollectOnce*
>(
user_data)->Collect();
549 context.AddNativeCallback(
560 event.pixel_ratio = 1.0;
562 ASSERT_TRUE(
engine.is_valid());
567 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
572 std::vector<FlutterMetalTextureHandle> textures{metal_texture.
texture};
574 bool resolve_called =
false;
577 resolve_called =
true;
578 auto res = std::make_unique<FlutterMetalExternalTexture>();
580 res->width = res->height = 100;
582 res->textures = textures.data();
583 res->num_textures = 1;
589 auto skia_surface =
surface->GetSurface();
596 .gr_context =
surface->GetGrContext().get(),
600 EXPECT_TRUE(resolve_called);
601 resolve_called =
false;
605 EXPECT_FALSE(resolve_called);
611 EXPECT_TRUE(resolve_called);
615 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
623 auto rendered_scene = context.GetNextSceneImage();
626 ASSERT_TRUE(
engine.is_valid());
633 event.pixel_ratio = 1.0;
640 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
648 auto rendered_scene = context.GetNextSceneImage();
651 ASSERT_TRUE(
engine.is_valid());
658 event.pixel_ratio = 1.0;
665 auto& context = GetEmbedderContext<EmbedderTestContextMetal>();
676 auto rendered_scene = context.GetNextSceneImage();
679 ASSERT_TRUE(
engine.is_valid());
686 event.pixel_ratio = 1.0;
Backend implementation of |DlCanvas| for |SkCanvas|.
std::function< std::unique_ptr< FlutterMetalExternalTexture >(int64_t, size_t, size_t)> ExternalTextureCallback
virtual void MarkNewFrameAvailable()=0
virtual void Paint(PaintContext &context, const DlRect &bounds, bool freeze, const DlImageSampling sampling)=0
void SetSurface(DlISize surface_size)
void SetRenderTargetType(EmbedderTestBackingStoreProducer::RenderTargetType type, FlutterSoftwarePixelFormat software_pixfmt=kFlutterSoftwarePixelFormatNative32)
void SetDartEntrypoint(std::string entrypoint)
void AddCommandLineArgument(std::string arg)
FlutterCompositor & GetCompositor()
UniqueEngine LaunchEngine() const
void SetCompositor(bool avoid_backing_store_cache=false, bool use_present_layers_callback=false)
TextureInfo CreateMetalTexture(const DlISize &size)
Returns texture_id = -1 when texture creation fails.
sk_sp< GrDirectContext > GetSkiaContext() const
FlutterEngineResult FlutterEngineRegisterExternalTexture(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Register an external texture with a unique (per engine) identifier. Only rendering backends that supp...
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
@ kFlutterLayerContentTypePlatformView
Indicates that the contents of this layer are determined by the embedder.
@ kFlutterLayerContentTypeBackingStore
@ kFlutterBackingStoreTypeMetal
Specifies a Metal backing store. This is backed by a Metal texture.
const void * FlutterMetalTextureHandle
Alias for id<MTLTexture>.
FlutterSize FlutterSizeMake(double width, double height)
FlutterRect FlutterRectMakeLTRB(double l, double t, double r, double b)
FlutterPoint FlutterPointMake(double x, double y)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_CHECK(condition)
TEST_F(DisplayListTest, Defaults)
sk_sp< SkSurface > CreateRenderSurface(const FlutterLayer &layer, GrDirectContext *context)
bool ImageMatchesFixture(const std::string &fixture_file_name, const sk_sp< SkImage > &scene_image)
static sk_sp< SkSurface > GetSurfaceFromTexture(const sk_sp< GrDirectContext > &skia_context, DlISize texture_size, void *texture)
impeller::ISize32 DlISize
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder h
FlutterBackingStoreType type
Specifies the type of backing store.
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStore).
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStorePresentInfo).
FlutterLayerContentType type
const FlutterBackingStore * backing_store
FlutterBackingStorePresentInfo * backing_store_present_info
const FlutterPlatformView * platform_view
size_t struct_size
This size of this struct. Must be sizeof(FlutterLayer).
FlutterSize size
The size of the layer (in physical pixels).
FlutterMetalTextureHandle * textures
size_t num_textures
Represents the size of the textures array.
FlutterMetalExternalTexturePixelFormat pixel_format
The pixel format type of the external.
size_t height
Height of the texture.
size_t width
Height of the texture.
size_t struct_size
The size of this struct. Must be sizeof(FlutterMetalTexture).
A structure to represent a rectangle.
A region represented by a collection of non-overlapping rectangles.
size_t struct_size
The size of this struct. Must be sizeof(FlutterRegion).
size_t struct_size
The size of this struct. Must be sizeof(FlutterWindowMetricsEvent).
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
#define CREATE_NATIVE_ENTRY(native_entry)