Flutter Impeller
impeller::interop::testing Namespace Reference

Classes

class  FlagObject
 
class  TestObject
 
class  PlaygroundTest
 

Typedefs

using InteropPlaygroundTest = PlaygroundTest
 

Functions

 INSTANTIATE_PLAYGROUND_SUITE (InteropPlaygroundTest)
 
 TEST_P (InteropPlaygroundTest, CanCreateContext)
 
 TEST_P (InteropPlaygroundTest, CanCreateDisplayListBuilder)
 
 TEST_P (InteropPlaygroundTest, CanCreateSurface)
 
 TEST_P (InteropPlaygroundTest, CanDrawRect)
 
 TEST_P (InteropPlaygroundTest, CanDrawImage)
 
 TEST_P (InteropPlaygroundTest, CanCreateOpenGLImage)
 
 TEST_P (InteropPlaygroundTest, ClearsOpenGLStancilStateAfterTransition)
 
 TEST_P (InteropPlaygroundTest, CanCreateParagraphs)
 
 TEST_P (InteropPlaygroundTest, CanCreateShapes)
 
 TEST_P (InteropPlaygroundTest, CanCreateParagraphsWithCustomFont)
 
static void DrawTextFrame (const hpp::TypographyContext &tc, hpp::DisplayListBuilder &builder, hpp::ParagraphStyle &p_style, const hpp::Paint &bg, ImpellerColor color, ImpellerTextAlignment align, float x_offset)
 
 TEST_P (InteropPlaygroundTest, CanRenderTextAlignments)
 
 TEST_P (InteropPlaygroundTest, CanRenderShadows)
 
 TEST_P (InteropPlaygroundTest, CanMeasureText)
 
 IMPELLER_DEFINE_HANDLE (FlagHandle)
 
 IMPELLER_DEFINE_HANDLE (TestHandle)
 
 TEST (InteropObjectTest, CanCreateScoped)
 
 TEST (InteropObjectTest, CanCreate)
 
 TEST (InteropObjectTest, CanCopyAssignMove)
 
static void SetupImpellerHPPProcTableOnce ()
 
static ScopedObject< SurfaceCreateSharedSurface (PlaygroundBackend backend, Context &context, std::shared_ptr< impeller::Surface > shared_surface)
 
static ScopedObject< ContextCreateSharedContext (PlaygroundBackend backend, std::shared_ptr< impeller::Context > shared_context)
 

Typedef Documentation

◆ InteropPlaygroundTest

Function Documentation

◆ CreateSharedContext()

static ScopedObject<Context> impeller::interop::testing::CreateSharedContext ( PlaygroundBackend  backend,
std::shared_ptr< impeller::Context shared_context 
)
static

Definition at line 146 of file playground_test.cc.

148  {
149  switch (backend) {
150 #if IMPELLER_ENABLE_METAL
151  case PlaygroundBackend::kMetal:
152  return ContextMTL::Create(shared_context);
153 #endif
154 #if IMPELLER_ENABLE_OPENGLES
155  case PlaygroundBackend::kOpenGLES:
156  return ContextGLES::Create(std::move(shared_context));
157 #endif
158 #if IMPELLER_ENABLE_VULKAN
159  case PlaygroundBackend::kVulkan:
160  return ContextVK::Create(std::move(shared_context));
161 #endif
162  default:
163  return nullptr;
164  }
165  FML_UNREACHABLE();
166 }
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161

References impeller::interop::ContextMTL::Create(), impeller::interop::ContextVK::Create(), impeller::interop::ContextGLES::Create(), impeller::kMetal, impeller::kOpenGLES, and impeller::kVulkan.

Referenced by impeller::interop::testing::PlaygroundTest::GetInteropContext().

◆ CreateSharedSurface()

static ScopedObject<Surface> impeller::interop::testing::CreateSharedSurface ( PlaygroundBackend  backend,
Context context,
std::shared_ptr< impeller::Surface shared_surface 
)
static

Definition at line 101 of file playground_test.cc.

104  {
105  switch (backend) {
106 #if IMPELLER_ENABLE_METAL
107  case PlaygroundBackend::kMetal:
108  return Adopt<Surface>(new SurfaceMTL(context, std::move(shared_surface)));
109 #endif
110 
111 #if IMPELLER_ENABLE_OPENGLES
112  case PlaygroundBackend::kOpenGLES:
113  return Adopt<Surface>(
114  new SurfaceGLES(context, std::move(shared_surface)));
115 #endif
116 
117 #if IMPELLER_ENABLE_VULKAN
118  case PlaygroundBackend::kVulkan:
119  return Adopt<Surface>(new SurfaceVK(context, std::move(shared_surface)));
120 #endif
121  default:
122  return nullptr;
123  }
124  FML_UNREACHABLE();
125 }

References impeller::kMetal, impeller::kOpenGLES, and impeller::kVulkan.

Referenced by impeller::interop::testing::PlaygroundTest::OpenPlaygroundHere().

◆ DrawTextFrame()

static void impeller::interop::testing::DrawTextFrame ( const hpp::TypographyContext &  tc,
hpp::DisplayListBuilder &  builder,
hpp::ParagraphStyle &  p_style,
const hpp::Paint &  bg,
ImpellerColor  color,
ImpellerTextAlignment  align,
float  x_offset 
)
static

Definition at line 399 of file impeller_unittests.cc.

405  {
406  const char text[] =
407  "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
408 
409  hpp::Paint fg;
410 
411  // Draw a box.
412  fg.SetColor(color);
413  fg.SetDrawStyle(kImpellerDrawStyleStroke);
414  ImpellerRect box_rect = {10 + x_offset, 10, 200, 200};
415  builder.DrawRect(box_rect, fg);
416 
417  // Draw text.
418  fg.SetDrawStyle(kImpellerDrawStyleFill);
419  p_style.SetForeground(fg);
420  p_style.SetBackground(bg);
421  p_style.SetTextAlignment(align);
422 
423  hpp::ParagraphBuilder p_builder(tc);
424  p_builder.PushStyle(p_style);
425  p_builder.AddText(reinterpret_cast<const uint8_t*>(text), sizeof(text));
426 
427  auto left_p = p_builder.Build(box_rect.width - 20.0);
428  ImpellerPoint pt = {20.0f + x_offset, 20.0f};
429  float w = left_p.GetMaxWidth();
430  float h = left_p.GetHeight();
431  builder.DrawParagraph(left_p, pt);
432  fg.SetDrawStyle(kImpellerDrawStyleStroke);
433 
434  // Draw an inner box around the paragraph layout.
435  ImpellerRect inner_box_rect = {pt.x, pt.y, w, h};
436  builder.DrawRect(inner_box_rect, fg);
437 }
@ kImpellerDrawStyleStroke
Definition: impeller.h:399
@ kImpellerDrawStyleFill
Definition: impeller.h:398
float width
Definition: impeller.h:481

References kImpellerDrawStyleFill, kImpellerDrawStyleStroke, ImpellerRect::width, ImpellerPoint::x, and ImpellerPoint::y.

Referenced by TEST_P().

◆ IMPELLER_DEFINE_HANDLE() [1/2]

impeller::interop::testing::IMPELLER_DEFINE_HANDLE ( FlagHandle  )

◆ IMPELLER_DEFINE_HANDLE() [2/2]

impeller::interop::testing::IMPELLER_DEFINE_HANDLE ( TestHandle  )

◆ INSTANTIATE_PLAYGROUND_SUITE()

impeller::interop::testing::INSTANTIATE_PLAYGROUND_SUITE ( InteropPlaygroundTest  )

◆ SetupImpellerHPPProcTableOnce()

static void impeller::interop::testing::SetupImpellerHPPProcTableOnce ( )
static

Definition at line 30 of file playground_test.cc.

30  {
31  static std::once_flag sOnceFlag;
32  std::call_once(sOnceFlag, []() {
33  std::map<std::string, void*> proc_map;
34 #define IMPELLER_HPP_PROC(name) \
35  proc_map[#name] = reinterpret_cast<void*>(&name);
37 #undef IMPELLER_HPP_PROC
39  [&](auto name) { return proc_map.at(name); });
40  });
41 }
#define IMPELLER_HPP_EACH_PROC(PROC)
Definition: impeller.hpp:47
bool Initialize(const std::function< void *(const char *function_name)> &resolver)
Definition: impeller.hpp:218
#define IMPELLER_HPP_PROC(name)

References IMPELLER_HPP_NAMESPACE::gGlobalProcTable, IMPELLER_HPP_EACH_PROC, IMPELLER_HPP_PROC, and IMPELLER_HPP_NAMESPACE::ProcTable::Initialize().

Referenced by impeller::interop::testing::PlaygroundTest::PlaygroundTest().

◆ TEST() [1/3]

impeller::interop::testing::TEST ( InteropObjectTest  ,
CanCopyAssignMove   
)

Definition at line 77 of file object_unittests.cc.

77  {
78  auto o = Create<TestObject>(1, 2.3, 'd');
79  ASSERT_EQ(o->GetRefCountForTests(), 1u);
80  {
81  auto o1 = o; // NOLINT(performance-unnecessary-copy-initialization)
82  ASSERT_EQ(o->GetRefCountForTests(), 2u);
83  auto o2 = o; // NOLINT(performance-unnecessary-copy-initialization)
84  ASSERT_EQ(o->GetRefCountForTests(), 3u);
85  auto o3 = o1; // NOLINT(performance-unnecessary-copy-initialization)
86  ASSERT_EQ(o->GetRefCountForTests(), 4u);
87  }
88  ASSERT_EQ(o->GetRefCountForTests(), 1u);
89 
90  {
91  auto o1(o); // NOLINT(performance-unnecessary-copy-initialization)
92  ASSERT_EQ(o->GetRefCountForTests(), 2u);
93  ASSERT_EQ(o1->GetRefCountForTests(), 2u);
94  }
95 
96  auto move_o = std::move(o);
97  ASSERT_EQ(move_o->GetRefCountForTests(), 1u);
98 }

◆ TEST() [2/3]

impeller::interop::testing::TEST ( InteropObjectTest  ,
CanCreate   
)

Definition at line 70 of file object_unittests.cc.

70  {
71  auto object = Create<TestObject>(1, 1.3, 'c');
72  ASSERT_EQ(object->GetArg1(), 1);
73  ASSERT_EQ(object->GetArg2(), 1.3);
74  ASSERT_EQ(object->GetArg3(), 'c');
75 }

◆ TEST() [3/3]

impeller::interop::testing::TEST ( InteropObjectTest  ,
CanCreateScoped   
)

Definition at line 54 of file object_unittests.cc.

54  {
55  bool destructed = false;
56  {
57  auto object = Adopt(new FlagObject(destructed)); //
58  }
59  ASSERT_TRUE(destructed);
60 
61  destructed = false;
62  {
63  auto object = Ref(new FlagObject(destructed));
64  // New objects start with retain count of 1.
65  object->Release();
66  }
67  ASSERT_TRUE(destructed);
68 }
ScopedObject< Object > Ref(Object *object)
Definition: object.h:146
ScopedObject< Object > Adopt(Object *object)
Definition: object.h:151

References impeller::interop::Adopt(), and impeller::interop::Ref().

◆ TEST_P() [1/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateContext   
)

Definition at line 30 of file impeller_unittests.cc.

30  {
31  auto context = CreateContext();
32  ASSERT_TRUE(context);
33 }
std::shared_ptr< Context > CreateContext()

References impeller::android::testing::CreateContext().

◆ TEST_P() [2/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateDisplayListBuilder   
)

Definition at line 35 of file impeller_unittests.cc.

35  {
36  hpp::DisplayListBuilder builder;
37  ASSERT_TRUE(builder);
38  ASSERT_TRUE(ToImpellerType(builder.GetTransform()).IsIdentity());
39  ASSERT_EQ(builder.GetSaveCount(), 1u);
40  builder.Save();
41  ASSERT_EQ(builder.GetSaveCount(), 2u);
42  builder.Restore();
43  ASSERT_EQ(builder.GetSaveCount(), 1u);
44 }
constexpr Matrix ToImpellerType(const ImpellerMatrix &m)
Definition: formats.h:201
constexpr bool IsIdentity() const
Definition: matrix.h:414

References impeller::Matrix::IsIdentity(), and impeller::interop::ToImpellerType().

◆ TEST_P() [3/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateOpenGLImage   
)

Definition at line 129 of file impeller_unittests.cc.

129  {
130  auto context = GetInteropContext();
131 
132  auto impeller_context = context->GetContext();
133 
134  if (impeller_context->GetBackendType() !=
136  GTEST_SKIP() << "This test works with OpenGL handles is only suitable for "
137  "that backend.";
138  return;
139  }
140 
141  const auto& gl_context = ContextGLES::Cast(*impeller_context);
142  const auto& gl = gl_context.GetReactor()->GetProcTable();
143 
144  constexpr ISize external_texture_size = {200, 300};
145 
146  Allocation texture_data;
147  ASSERT_TRUE(
148  texture_data.Truncate(Bytes{external_texture_size.Area() * 4u}, false));
149 
150  const auto kClearColor = Color::Fuchsia().ToR8G8B8A8();
151 
152  for (size_t i = 0; i < external_texture_size.Area() * 4u; i += 4u) {
153  memcpy(texture_data.GetBuffer() + i, kClearColor.data(), 4);
154  }
155 
156  GLuint external_texture = GL_NONE;
157  gl.GenTextures(1u, &external_texture);
158  ASSERT_NE(external_texture, 0u);
159  gl.BindTexture(GL_TEXTURE_2D, external_texture);
160  gl.TexImage2D(GL_TEXTURE_2D, //
161  0, //
162  GL_RGBA, //
163  external_texture_size.width, //
164  external_texture_size.height, //
165  0, //
166  GL_RGBA, //
167  GL_UNSIGNED_BYTE, //
168  texture_data.GetBuffer() //
169  );
170 
171  ImpellerTextureDescriptor desc = {};
173  desc.size = {external_texture_size.width, external_texture_size.height};
174  desc.mip_count = 1u;
175  auto texture = Adopt<Texture>(ImpellerTextureCreateWithOpenGLTextureHandleNew(
176  context.GetC(), //
177  &desc, //
178  external_texture //
179  ));
180  ASSERT_TRUE(texture);
181 
182  ASSERT_EQ(ImpellerTextureGetOpenGLHandle(texture.GetC()), external_texture);
183 
184  auto builder =
185  Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
186  ImpellerPoint point = {100, 100};
187  ImpellerDisplayListBuilderDrawTexture(builder.GetC(), texture.GetC(), &point,
189  nullptr);
190  auto dl = Adopt<DisplayList>(
192  ASSERT_TRUE(
193  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
194  ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
195  return true;
196  }));
197 }
@ kImpellerTextureSamplingLinear
Definition: impeller.h:421
IMPELLER_EXPORT void ImpellerDisplayListBuilderDrawTexture(ImpellerDisplayListBuilder IMPELLER_NONNULL builder, ImpellerTexture IMPELLER_NONNULL texture, const ImpellerPoint *IMPELLER_NONNULL point, ImpellerTextureSampling sampling, ImpellerPaint IMPELLER_NULLABLE paint)
Draw a texture at the specified point.
IMPELLER_EXPORT uint64_t ImpellerTextureGetOpenGLHandle(ImpellerTexture IMPELLER_NONNULL texture)
Get the OpenGL handle associated with this texture. If this is not an OpenGL texture,...
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerDisplayList IMPELLER_NULLABLE ImpellerDisplayListBuilderCreateDisplayListNew(ImpellerDisplayListBuilder IMPELLER_NONNULL builder)
Create a new display list using the rendering intent already encoded in the builder....
IMPELLER_EXPORT bool ImpellerSurfaceDrawDisplayList(ImpellerSurface IMPELLER_NONNULL surface, ImpellerDisplayList IMPELLER_NONNULL display_list)
Draw a display list onto the surface. The same display list can be drawn multiple times to different ...
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerTexture IMPELLER_NULLABLE ImpellerTextureCreateWithOpenGLTextureHandleNew(ImpellerContext IMPELLER_NONNULL context, const ImpellerTextureDescriptor *IMPELLER_NONNULL descriptor, uint64_t handle)
Create a texture with an externally created OpenGL texture handle.
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerDisplayListBuilder IMPELLER_NULLABLE ImpellerDisplayListBuilderNew(const ImpellerRect *IMPELLER_NULLABLE cull_rect)
Create a new display list builder.
@ kImpellerPixelFormatRGBA8888
Definition: impeller.h:416
AllocationSize< 1u > Bytes
ISize64 ISize
Definition: size.h:162
int64_t width
Definition: impeller.h:496
ImpellerPixelFormat pixel_format
Definition: impeller.h:597
ImpellerISize size
Definition: impeller.h:598

References impeller::BackendCast< ContextGLES, Context >::Cast(), impeller::Color::Fuchsia(), impeller::Allocation::GetBuffer(), impeller::interop::ImpellerDisplayListBuilderCreateDisplayListNew(), impeller::interop::ImpellerDisplayListBuilderDrawTexture(), impeller::interop::ImpellerDisplayListBuilderNew(), impeller::interop::ImpellerSurfaceDrawDisplayList(), impeller::interop::ImpellerTextureCreateWithOpenGLTextureHandleNew(), impeller::interop::ImpellerTextureGetOpenGLHandle(), kImpellerPixelFormatRGBA8888, kImpellerTextureSamplingLinear, impeller::Context::kOpenGLES, ImpellerTextureDescriptor::mip_count, ImpellerTextureDescriptor::pixel_format, ImpellerTextureDescriptor::size, impeller::Color::ToR8G8B8A8(), impeller::Allocation::Truncate(), and ImpellerISize::width.

◆ TEST_P() [4/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateParagraphs   
)

Definition at line 237 of file impeller_unittests.cc.

237  {
238  // Create a typography context.
239  hpp::TypographyContext type_context;
240  ASSERT_TRUE(type_context);
241 
242  // Create a builder.
243  hpp::ParagraphBuilder builder(type_context);
244  ASSERT_TRUE(builder);
245 
246  // Create a paragraph style with the font size and foreground and background
247  // colors.
248  hpp::ParagraphStyle style;
249  ASSERT_TRUE(style);
250  style.SetFontSize(150.0f);
251  style.SetHeight(2.0f);
252 
253  {
254  hpp::Paint paint;
255  ASSERT_TRUE(paint);
256  paint.SetColor({1.0, 0.0, 0.0, 1.0});
257  style.SetForeground(paint);
258  }
259 
260  {
261  hpp::Paint paint;
262  paint.SetColor({1.0, 1.0, 1.0, 1.0});
263  style.SetBackground(paint);
264  }
265 
266  // Push the style onto the style stack.
267  builder.PushStyle(style);
268  std::string text = "the ⚡️ quick ⚡️ brown 🦊 fox jumps over the lazy dog 🐶.";
269 
270  // Add the paragraph text data.
271  builder.AddText(text);
272 
273  // Layout and build the paragraph.
274  auto paragraph = builder.Build(1200.0f);
275  ASSERT_TRUE(paragraph);
276 
277  // Create a display list with just the paragraph drawn into it.
278  hpp::DisplayListBuilder dl_builder;
279  dl_builder.DrawParagraph(paragraph, {20, 20});
280 
281  // Build the display list.
282  auto dl = dl_builder.Build();
283 
284  ASSERT_TRUE(
285  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
286  hpp::Surface window(surface.GetC());
287  window.Draw(dl);
288  return true;
289  }));
290 }

◆ TEST_P() [5/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateParagraphsWithCustomFont   
)

Definition at line 325 of file impeller_unittests.cc.

325  {
326  // Create a typography context.
327  auto type_context = Adopt<TypographyContext>(ImpellerTypographyContextNew());
328  ASSERT_TRUE(type_context);
329 
330  // Open the custom font file.
331  std::unique_ptr<fml::Mapping> font_data =
332  flutter::testing::OpenFixtureAsMapping("wtf.otf");
333  ASSERT_NE(font_data, nullptr);
334  ASSERT_GT(font_data->GetSize(), 0u);
335  ImpellerMapping font_data_mapping = {
336  .data = font_data->GetMapping(),
337  .length = font_data->GetSize(),
338  .on_release = [](auto ctx) {
339  delete reinterpret_cast<fml::Mapping*>(ctx);
340  }};
341  auto registered =
342  ImpellerTypographyContextRegisterFont(type_context.GetC(), //
343  &font_data_mapping, //
344  font_data.release(), //
345  nullptr //
346  );
347  ASSERT_TRUE(registered);
348 
349  // Create a builder.
350  auto builder =
351  Adopt<ParagraphBuilder>(ImpellerParagraphBuilderNew(type_context.GetC()));
352  ASSERT_TRUE(builder);
353 
354  // Create a paragraph style with the font size and foreground and background
355  // colors.
356  auto style = Adopt<ParagraphStyle>(ImpellerParagraphStyleNew());
357  ASSERT_TRUE(style);
358  ImpellerParagraphStyleSetFontSize(style.GetC(), 150.0f);
359  ImpellerParagraphStyleSetFontFamily(style.GetC(), "WhatTheFlutter");
360 
361  {
362  auto paint = Adopt<Paint>(ImpellerPaintNew());
363  ASSERT_TRUE(paint);
364  ImpellerColor color = {0.0, 1.0, 1.0, 1.0};
365  ImpellerPaintSetColor(paint.GetC(), &color);
366  ImpellerParagraphStyleSetForeground(style.GetC(), paint.GetC());
367  }
368 
369  // Push the style onto the style stack.
370  ImpellerParagraphBuilderPushStyle(builder.GetC(), style.GetC());
371  std::string text = "0F0F0F0";
372 
373  // Add the paragraph text data.
374  ImpellerParagraphBuilderAddText(builder.GetC(),
375  reinterpret_cast<const uint8_t*>(text.data()),
376  text.size());
377 
378  // Layout and build the paragraph.
379  auto paragraph = Adopt<Paragraph>(
380  ImpellerParagraphBuilderBuildParagraphNew(builder.GetC(), 1200.0f));
381  ASSERT_TRUE(paragraph);
382 
383  // Create a display list with just the paragraph drawn into it.
384  auto dl_builder =
385  Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
386  ImpellerPoint point = {20, 20};
387  ImpellerDisplayListBuilderDrawParagraph(dl_builder.GetC(), paragraph.GetC(),
388  &point);
389  auto dl = Adopt<DisplayList>(
391 
392  ASSERT_TRUE(
393  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
394  ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
395  return true;
396  }));
397 } // namespace impeller::interop::testing
IMPELLER_EXPORT void ImpellerDisplayListBuilderDrawParagraph(ImpellerDisplayListBuilder IMPELLER_NONNULL builder, ImpellerParagraph IMPELLER_NONNULL paragraph, const ImpellerPoint *IMPELLER_NONNULL point)
Draw a paragraph at the specified point.
IMPELLER_EXPORT bool ImpellerTypographyContextRegisterFont(ImpellerTypographyContext IMPELLER_NONNULL context, const ImpellerMapping *IMPELLER_NONNULL contents, void *IMPELLER_NULLABLE contents_on_release_user_data, const char *IMPELLER_NULLABLE family_name_alias)
Register a custom font.
IMPELLER_EXPORT void ImpellerParagraphBuilderAddText(ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder, const uint8_t *IMPELLER_NULLABLE data, uint32_t length)
Add UTF-8 encoded text to the paragraph. The text will be styled according to the paragraph style alr...
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerPaint IMPELLER_NULLABLE ImpellerPaintNew()
Create a new paint with default values.
IMPELLER_EXPORT void ImpellerPaintSetColor(ImpellerPaint IMPELLER_NONNULL paint, const ImpellerColor *IMPELLER_NONNULL color)
Set the paint color.
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerParagraph IMPELLER_NULLABLE ImpellerParagraphBuilderBuildParagraphNew(ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder, float width)
Layout and build a new paragraph using the specified width. The resulting paragraph is immutable....
IMPELLER_EXPORT void ImpellerParagraphBuilderPushStyle(ImpellerParagraphBuilder IMPELLER_NONNULL paragraph_builder, ImpellerParagraphStyle IMPELLER_NONNULL style)
Push a new paragraph style onto the paragraph style stack managed by the paragraph builder.
IMPELLER_EXPORT void ImpellerParagraphStyleSetFontSize(ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, float size)
Set the font size.
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerParagraphStyle IMPELLER_NULLABLE ImpellerParagraphStyleNew()
Create a new paragraph style.
IMPELLER_EXPORT void ImpellerParagraphStyleSetForeground(ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, ImpellerPaint IMPELLER_NONNULL paint)
Set the paint used to render the text glyph contents.
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerTypographyContext IMPELLER_NULLABLE ImpellerTypographyContextNew()
Create a new typography contents.
IMPELLER_EXPORT void ImpellerParagraphStyleSetFontFamily(ImpellerParagraphStyle IMPELLER_NONNULL paragraph_style, const char *IMPELLER_NONNULL family_name)
Set the font family.
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerParagraphBuilder IMPELLER_NULLABLE ImpellerParagraphBuilderNew(ImpellerTypographyContext IMPELLER_NONNULL context)
Create a new paragraph builder.
const uint8_t *IMPELLER_NONNULL data
Definition: impeller.h:603

References ImpellerMapping::data, impeller::interop::ImpellerDisplayListBuilderCreateDisplayListNew(), impeller::interop::ImpellerDisplayListBuilderDrawParagraph(), impeller::interop::ImpellerDisplayListBuilderNew(), impeller::interop::ImpellerPaintNew(), impeller::interop::ImpellerPaintSetColor(), impeller::interop::ImpellerParagraphBuilderAddText(), impeller::interop::ImpellerParagraphBuilderBuildParagraphNew(), impeller::interop::ImpellerParagraphBuilderNew(), impeller::interop::ImpellerParagraphBuilderPushStyle(), impeller::interop::ImpellerParagraphStyleNew(), impeller::interop::ImpellerParagraphStyleSetFontFamily(), impeller::interop::ImpellerParagraphStyleSetFontSize(), impeller::interop::ImpellerParagraphStyleSetForeground(), impeller::interop::ImpellerSurfaceDrawDisplayList(), impeller::interop::ImpellerTypographyContextNew(), and impeller::interop::ImpellerTypographyContextRegisterFont().

◆ TEST_P() [6/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateShapes   
)

Definition at line 292 of file impeller_unittests.cc.

292  {
293  hpp::DisplayListBuilder builder;
294 
295  hpp::Paint red_paint;
296  red_paint.SetColor({1.0, 0.0, 0.0, 1.0});
297  red_paint.SetStrokeWidth(10.0);
298 
299  builder.Translate(10, 10);
300  builder.DrawRect({0, 0, 100, 100}, red_paint);
301  builder.Translate(100, 100);
302  builder.DrawOval({0, 0, 100, 100}, red_paint);
303  builder.Translate(100, 100);
304  builder.DrawLine({0, 0}, {100, 100}, red_paint);
305 
306  builder.Translate(100, 100);
307  ImpellerRoundingRadii radii = {};
308  radii.top_left = {10, 10};
309  radii.bottom_right = {10, 10};
310  builder.DrawRoundedRect({0, 0, 100, 100}, radii, red_paint);
311 
312  builder.Translate(100, 100);
313  builder.DrawPath(hpp::PathBuilder{}.AddOval({0, 0, 100, 100}).Build(),
314  red_paint);
315 
316  auto dl = builder.Build();
317  ASSERT_TRUE(
318  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
319  hpp::Surface window(surface.GetC());
320  window.Draw(dl);
321  return true;
322  }));
323 }
ImpellerPoint top_left
Definition: impeller.h:582
ImpellerPoint bottom_right
Definition: impeller.h:585

References ImpellerRoundingRadii::bottom_right, and ImpellerRoundingRadii::top_left.

◆ TEST_P() [7/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanCreateSurface   
)

Definition at line 46 of file impeller_unittests.cc.

46  {
47  if (GetBackend() != PlaygroundBackend::kOpenGLES) {
48  GTEST_SKIP()
49  << "This test checks wrapping FBOs which is an OpenGL ES only call.";
50  return;
51  }
52  auto context = CreateContext();
53  ASSERT_TRUE(context);
54  const auto window_size = GetWindowSize();
55  ImpellerISize size = {window_size.width, window_size.height};
56  auto surface = Adopt<Surface>(ImpellerSurfaceCreateWrappedFBONew(
57  context.GetC(), //
58  0u, //
60  &size) //
61  );
62  ASSERT_TRUE(surface);
63 }
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerSurface IMPELLER_NULLABLE ImpellerSurfaceCreateWrappedFBONew(ImpellerContext IMPELLER_NONNULL context, uint64_t fbo, ImpellerPixelFormat format, const ImpellerISize *IMPELLER_NONNULL size)
Create a new surface by wrapping an existing framebuffer object. The framebuffer must be complete as ...

References impeller::android::testing::CreateContext(), impeller::interop::ImpellerSurfaceCreateWrappedFBONew(), kImpellerPixelFormatRGBA8888, impeller::kOpenGLES, and ImpellerISize::width.

◆ TEST_P() [8/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanDrawImage   
)

Definition at line 96 of file impeller_unittests.cc.

96  {
97  auto compressed = LoadFixtureImageCompressed(
98  flutter::testing::OpenFixtureAsMapping("boston.jpg"));
99  ASSERT_NE(compressed, nullptr);
100  auto decompressed = compressed->Decode().ConvertToRGBA();
101  ASSERT_TRUE(decompressed.IsValid());
102  ImpellerMapping mapping = {};
103  mapping.data = decompressed.GetAllocation()->GetMapping();
104  mapping.length = decompressed.GetAllocation()->GetSize();
105 
106  auto context = GetInteropContext();
107  ImpellerTextureDescriptor desc = {};
109  desc.size = {decompressed.GetSize().width, decompressed.GetSize().height};
110  desc.mip_count = 1u;
111  auto texture = Adopt<Texture>(ImpellerTextureCreateWithContentsNew(
112  context.GetC(), &desc, &mapping, nullptr));
113  ASSERT_TRUE(texture);
114  auto builder =
115  Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
116  ImpellerPoint point = {100, 100};
117  ImpellerDisplayListBuilderDrawTexture(builder.GetC(), texture.GetC(), &point,
119  nullptr);
120  auto dl = Adopt<DisplayList>(
122  ASSERT_TRUE(
123  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
124  ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
125  return true;
126  }));
127 }
IMPELLER_EXPORT IMPELLER_NODISCARD ImpellerTexture IMPELLER_NULLABLE ImpellerTextureCreateWithContentsNew(ImpellerContext IMPELLER_NONNULL context, const ImpellerTextureDescriptor *IMPELLER_NONNULL descriptor, const ImpellerMapping *IMPELLER_NONNULL contents, void *IMPELLER_NULLABLE contents_on_release_user_data)
Create a texture with decompressed bytes.
uint64_t length
Definition: impeller.h:604

References ImpellerMapping::data, impeller::interop::ImpellerDisplayListBuilderCreateDisplayListNew(), impeller::interop::ImpellerDisplayListBuilderDrawTexture(), impeller::interop::ImpellerDisplayListBuilderNew(), impeller::interop::ImpellerSurfaceDrawDisplayList(), impeller::interop::ImpellerTextureCreateWithContentsNew(), kImpellerPixelFormatRGBA8888, kImpellerTextureSamplingLinear, ImpellerMapping::length, ImpellerTextureDescriptor::mip_count, ImpellerTextureDescriptor::pixel_format, ImpellerTextureDescriptor::size, and ImpellerISize::width.

◆ TEST_P() [9/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanDrawRect   
)

Definition at line 65 of file impeller_unittests.cc.

65  {
66  auto builder =
67  Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
68  auto paint = Adopt<Paint>(ImpellerPaintNew());
69  ImpellerColor color = {0.0, 0.0, 1.0, 1.0};
70  ImpellerPaintSetColor(paint.GetC(), &color);
71  ImpellerRect rect = {10, 20, 100, 200};
72  ImpellerDisplayListBuilderDrawRect(builder.GetC(), &rect, paint.GetC());
73  color = {1.0, 0.0, 0.0, 1.0};
74  ImpellerPaintSetColor(paint.GetC(), &color);
75  ImpellerDisplayListBuilderTranslate(builder.GetC(), 110, 210);
76  ImpellerMatrix scale_transform = {
77  // clang-format off
78  2.0, 0.0, 0.0, 0.0, //
79  0.0, 2.0, 0.0, 0.0, //
80  0.0, 0.0, 1.0, 0.0, //
81  0.0, 0.0, 0.0, 1.0, //
82  // clang-format on
83  };
84  ImpellerDisplayListBuilderTransform(builder.GetC(), &scale_transform);
85  ImpellerDisplayListBuilderDrawRect(builder.GetC(), &rect, paint.GetC());
86  auto dl = Adopt<DisplayList>(
88  ASSERT_TRUE(dl);
89  ASSERT_TRUE(
90  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
91  ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
92  return true;
93  }));
94 }
IMPELLER_EXPORT void ImpellerDisplayListBuilderTranslate(ImpellerDisplayListBuilder IMPELLER_NONNULL builder, float x_translation, float y_translation)
Apply a translation to the transformation matrix currently on top of the save stack.
IMPELLER_EXPORT void ImpellerDisplayListBuilderTransform(ImpellerDisplayListBuilder IMPELLER_NONNULL builder, const ImpellerMatrix *IMPELLER_NONNULL transform)
Appends the the provided transformation to the transformation already on the save stack.
IMPELLER_EXPORT void ImpellerDisplayListBuilderDrawRect(ImpellerDisplayListBuilder IMPELLER_NONNULL builder, const ImpellerRect *IMPELLER_NONNULL rect, ImpellerPaint IMPELLER_NONNULL paint)
Draws a rectangle.

References impeller::interop::ImpellerDisplayListBuilderCreateDisplayListNew(), impeller::interop::ImpellerDisplayListBuilderDrawRect(), impeller::interop::ImpellerDisplayListBuilderNew(), impeller::interop::ImpellerDisplayListBuilderTransform(), impeller::interop::ImpellerDisplayListBuilderTranslate(), impeller::interop::ImpellerPaintNew(), impeller::interop::ImpellerPaintSetColor(), and impeller::interop::ImpellerSurfaceDrawDisplayList().

◆ TEST_P() [10/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanMeasureText   
)

Definition at line 507 of file impeller_unittests.cc.

507  {
508  hpp::TypographyContext type_context;
509  hpp::ParagraphBuilder paragraph_builder(type_context);
510  hpp::ParagraphStyle paragraph_style;
511  paragraph_style.SetFontSize(50);
512  paragraph_builder.PushStyle(paragraph_style);
513  const std::string text =
514  "🏁 Can 👨‍👨‍👦‍👦 Measure 🔍 Text\nAnd this is line "
515  "two.\nWhoa! Three lines. How high does this go?\r\nI stopped counting.";
516  const auto u16text = fml::Utf8ToUtf16(text);
517  ASSERT_NE(text.size(), u16text.size());
518  paragraph_builder.AddText(reinterpret_cast<const uint8_t*>(text.data()),
519  text.size());
520  hpp::DisplayListBuilder builder;
521  // Don't rely on implicit line breaks in this test to make it less brittle to
522  // different fonts being picked.
523  hpp::Paragraph paragraph = paragraph_builder.Build(FLT_MAX);
524  const auto line_count = paragraph.GetLineCount();
525  ASSERT_EQ(line_count, 4u);
526 
527  // Line Metrics.
528  {
529  auto metrics = paragraph.GetLineMetrics();
530  ASSERT_GT(metrics.GetAscent(0), 0.0);
531  ASSERT_GT(metrics.GetUnscaledAscent(0), 0.0);
532  ASSERT_GT(metrics.GetDescent(0), 0.0);
533  ASSERT_GT(metrics.GetBaseline(0), 0.0);
534  ASSERT_TRUE(metrics.IsHardbreak(0));
535  ASSERT_DOUBLE_EQ(metrics.GetLeft(0), 0.0);
536  ASSERT_EQ(metrics.GetCodeUnitStartIndex(0), 0u);
537  ASSERT_EQ(metrics.GetCodeUnitEndIndexIncludingNewline(0),
538  metrics.GetCodeUnitEndIndex(0) + 1u);
539  ASSERT_GT(metrics.GetCodeUnitStartIndex(1), 0u);
540  // Last line should cover the entire range.
541  ASSERT_EQ(metrics.GetCodeUnitEndIndex(3), u16text.size());
542  }
543 
544  // Glyph info by code point.
545  {
546  auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
547  ASSERT_TRUE(glyph);
548  ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeBegin(), 0u);
549  ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
550  fml::Utf8ToUtf16("🏁").size());
551  auto bounds = glyph.GetGraphemeClusterBounds();
552  ASSERT_GT(bounds.width, 0.0);
553  ASSERT_GT(bounds.height, 0.0);
554  ASSERT_FALSE(glyph.IsEllipsis());
555  ASSERT_EQ(glyph.GetTextDirection(), kImpellerTextDirectionLTR);
556  }
557 
558  // Glyph info by coordinates.
559  {
560  auto glyph = paragraph.GlyphInfoAtParagraphCoordinates(0.0, 0.0);
561  ASSERT_TRUE(glyph);
562  ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
563  fml::Utf8ToUtf16("🏁").size());
564  }
565 
566  // Glyph Figure out word boundaries.
567  {
568  auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
569  ASSERT_TRUE(glyph);
570  auto range =
571  paragraph.GetWordBoundary(glyph.GetGraphemeClusterCodeUnitRangeEnd());
572  ASSERT_GT(range.end, 0u);
573  }
574 
575  builder.DrawParagraph(paragraph, ImpellerPoint{100, 100});
576  auto dl = builder.Build();
577  ASSERT_TRUE(
578  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
579  hpp::Surface window(surface.GetC());
580  window.Draw(dl);
581  return true;
582  }));
583 }
@ kImpellerTextDirectionLTR
Definition: impeller.h:472

References kImpellerTextDirectionLTR.

◆ TEST_P() [11/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanRenderShadows   
)

Definition at line 478 of file impeller_unittests.cc.

478  {
479  hpp::DisplayListBuilder builder;
480  {
481  builder.DrawRect(ImpellerRect{0, 0, 400, 400},
482  hpp::Paint{}.SetColor(ImpellerColor{
483  0.0, 1.0, 0.0, 1.0, kImpellerColorSpaceSRGB}));
484  }
485  ImpellerRect box = {100, 100, 100, 100};
486  {
487  hpp::PathBuilder path_builder;
488  path_builder.AddRect(box);
489  ImpellerColor shadow_color = {0.0, 0.0, 0.0, 1.0, kImpellerColorSpaceSRGB};
490  builder.DrawShadow(path_builder.Build(), shadow_color, 4.0f, false, 1.0f);
491  }
492  {
493  hpp::Paint red_paint;
494  red_paint.SetColor(
495  ImpellerColor{1.0, 0.0, 0.0, 1.0, kImpellerColorSpaceSRGB});
496  builder.DrawRect(box, red_paint);
497  }
498  auto dl = builder.Build();
499  ASSERT_TRUE(
500  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
501  hpp::Surface window(surface.GetC());
502  window.Draw(dl);
503  return true;
504  }));
505 }
@ kImpellerColorSpaceSRGB
Definition: impeller.h:439

References kImpellerColorSpaceSRGB.

◆ TEST_P() [12/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
CanRenderTextAlignments   
)

Definition at line 439 of file impeller_unittests.cc.

439  {
440  hpp::TypographyContext tc;
441 
442  hpp::DisplayListBuilder builder;
443  hpp::Paint bg;
444  hpp::ParagraphStyle p_style;
445  p_style.SetFontFamily("Roboto");
446  p_style.SetFontSize(24.0);
447  p_style.SetFontWeight(kImpellerFontWeight400);
448 
449  // Clear the background to a white color.
450  ImpellerColor clear_color = {1.0, 1.0, 1.0, 1.0};
451  bg.SetColor(clear_color);
452  builder.DrawPaint(bg);
453 
454  // Draw red, left-aligned text.
455  ImpellerColor red = {1.0, 0.0, 0.0, 1.0};
456  DrawTextFrame(tc, builder, p_style, bg, red, kImpellerTextAlignmentLeft, 0.0);
457 
458  // Draw green, centered text.
459  ImpellerColor green = {0.0, 1.0, 0.0, 1.0};
460  DrawTextFrame(tc, builder, p_style, bg, green, kImpellerTextAlignmentCenter,
461  220.0);
462 
463  // Draw blue, right-aligned text.
464  ImpellerColor blue = {0.0, 0.0, 1.0, 1.0};
465  DrawTextFrame(tc, builder, p_style, bg, blue, kImpellerTextAlignmentRight,
466  440.0);
467 
468  auto dl = builder.Build();
469 
470  ASSERT_TRUE(
471  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
472  hpp::Surface window(surface.GetC());
473  window.Draw(dl);
474  return true;
475  }));
476 }
@ kImpellerFontWeight400
Definition: impeller.h:448
@ kImpellerTextAlignmentLeft
Definition: impeller.h:462
@ kImpellerTextAlignmentCenter
Definition: impeller.h:464
@ kImpellerTextAlignmentRight
Definition: impeller.h:463
static void DrawTextFrame(const hpp::TypographyContext &tc, hpp::DisplayListBuilder &builder, hpp::ParagraphStyle &p_style, const hpp::Paint &bg, ImpellerColor color, ImpellerTextAlignment align, float x_offset)

References DrawTextFrame(), kImpellerFontWeight400, kImpellerTextAlignmentCenter, kImpellerTextAlignmentLeft, and kImpellerTextAlignmentRight.

◆ TEST_P() [13/13]

impeller::interop::testing::TEST_P ( InteropPlaygroundTest  ,
ClearsOpenGLStancilStateAfterTransition   
)

Definition at line 199 of file impeller_unittests.cc.

199  {
200  auto context = GetInteropContext();
201  auto impeller_context = context->GetContext();
202  if (impeller_context->GetBackendType() !=
204  GTEST_SKIP() << "This test works with OpenGL handles is only suitable for "
205  "that backend.";
206  return;
207  }
208  const auto& gl_context = ContextGLES::Cast(*impeller_context);
209  const auto& gl = gl_context.GetReactor()->GetProcTable();
210  auto builder =
211  Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
212  auto paint = Adopt<Paint>(ImpellerPaintNew());
213  ImpellerColor color = {0.0, 0.0, 1.0, 1.0};
214  ImpellerPaintSetColor(paint.GetC(), &color);
215  ImpellerRect rect = {10, 20, 100, 200};
216  ImpellerDisplayListBuilderDrawRect(builder.GetC(), &rect, paint.GetC());
217  color = {1.0, 0.0, 0.0, 1.0};
218  ImpellerPaintSetColor(paint.GetC(), &color);
219  ImpellerDisplayListBuilderTranslate(builder.GetC(), 110, 210);
220  ImpellerDisplayListBuilderClipRect(builder.GetC(), &rect,
222  ImpellerDisplayListBuilderDrawRect(builder.GetC(), &rect, paint.GetC());
223  auto dl = Adopt<DisplayList>(
225  ASSERT_TRUE(dl);
226  ASSERT_TRUE(
227  OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
228  ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
229  // OpenGL state is reset even though the operations above enable a
230  // stencil check.
231  GLboolean stencil_enabled = true;
232  gl.GetBooleanv(GL_STENCIL_TEST, &stencil_enabled);
233  return stencil_enabled == GL_FALSE;
234  }));
235 }
IMPELLER_EXPORT void ImpellerDisplayListBuilderClipRect(ImpellerDisplayListBuilder IMPELLER_NONNULL builder, const ImpellerRect *IMPELLER_NONNULL rect, ImpellerClipOperation op)
Reduces the clip region to the intersection of the current clip and the given rectangle taking into a...
@ kImpellerClipOperationDifference
Definition: impeller.h:361

References impeller::BackendCast< ContextGLES, Context >::Cast(), impeller::interop::ImpellerDisplayListBuilderClipRect(), impeller::interop::ImpellerDisplayListBuilderCreateDisplayListNew(), impeller::interop::ImpellerDisplayListBuilderDrawRect(), impeller::interop::ImpellerDisplayListBuilderNew(), impeller::interop::ImpellerDisplayListBuilderTranslate(), impeller::interop::ImpellerPaintNew(), impeller::interop::ImpellerPaintSetColor(), impeller::interop::ImpellerSurfaceDrawDisplayList(), kImpellerClipOperationDifference, and impeller::Context::kOpenGLES.