| Flutter Impeller |

impeller_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/testing/testing.h"
6 #include "impeller/base/allocation.h"
7 #include "impeller/renderer/backend/gles/context_gles.h"
8 #include "impeller/toolkit/interop/context.h"
9 #include "impeller/toolkit/interop/dl.h"
10 #include "impeller/toolkit/interop/dl_builder.h"
11 #include "impeller/toolkit/interop/formats.h"
12 #include "impeller/toolkit/interop/impeller.h"
13 #include "impeller/toolkit/interop/paint.h"
14 #include "impeller/toolkit/interop/paragraph.h"
15 #include "impeller/toolkit/interop/paragraph_builder.h"
16 #include "impeller/toolkit/interop/paragraph_style.h"
17 #include "impeller/toolkit/interop/playground_test.h"
18 #include "impeller/toolkit/interop/surface.h"
19 #include "impeller/toolkit/interop/texture.h"
20 #include "impeller/toolkit/interop/typography_context.h"
21
22 namespace impeller::interop::testing {
23
24 using InteropPlaygroundTest = PlaygroundTest;
25 INSTANTIATE_OPENGLES_PLAYGROUND_SUITE(InteropPlaygroundTest);
26
27 TEST_P(InteropPlaygroundTest, CanCreateContext) {
28 auto context = CreateContext();
29 ASSERT_TRUE(context);
30 }
31
32 TEST_P(InteropPlaygroundTest, CanCreateDisplayListBuilder) {
33 auto builder = ImpellerDisplayListBuilderNew(nullptr);
34 ASSERT_NE(builder, nullptr);
35 ImpellerMatrix matrix;
36 ImpellerDisplayListBuilderGetTransform(builder, &matrix);
37 ASSERT_TRUE(ToImpellerType(matrix).IsIdentity());
38 ASSERT_EQ(ImpellerDisplayListBuilderGetSaveCount(builder), 1u);
39 ImpellerDisplayListBuilderSave(builder);
40 ASSERT_EQ(ImpellerDisplayListBuilderGetSaveCount(builder), 2u);
41 // ImpellerDisplayListBuilderSave(nullptr); <-- Compiler error.
42 ImpellerDisplayListBuilderRestore(builder);
43 ASSERT_EQ(ImpellerDisplayListBuilderGetSaveCount(builder), 1u);
44 ImpellerDisplayListBuilderRelease(builder);
45 }
46
47 TEST_P(InteropPlaygroundTest, CanCreateSurface) {
48 auto context = CreateContext();
49 ASSERT_TRUE(context);
50 const auto window_size = GetWindowSize();
51 ImpellerISize size = {window_size.width, window_size.height};
52 auto surface = Adopt<Surface>(ImpellerSurfaceCreateWrappedFBONew(
53 context.GetC(), //
54 0u, //
55 ImpellerPixelFormat::kImpellerPixelFormatRGBA8888, //
56 &size) //
57 );
58 ASSERT_TRUE(surface);
59 }
60
61 TEST_P(InteropPlaygroundTest, CanDrawRect) {
62 auto builder =
63 Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
64 auto paint = Adopt<Paint>(ImpellerPaintNew());
65 ImpellerColor color = {0.0, 0.0, 1.0, 1.0};
66 ImpellerPaintSetColor(paint.GetC(), &color);
67 ImpellerRect rect = {10, 20, 100, 200};
68 ImpellerDisplayListBuilderDrawRect(builder.GetC(), &rect, paint.GetC());
69 color = {1.0, 0.0, 0.0, 1.0};
70 ImpellerPaintSetColor(paint.GetC(), &color);
71 ImpellerDisplayListBuilderTranslate(builder.GetC(), 110, 210);
72 ImpellerDisplayListBuilderDrawRect(builder.GetC(), &rect, paint.GetC());
73 auto dl = Adopt<DisplayList>(
74 ImpellerDisplayListBuilderCreateDisplayListNew(builder.GetC()));
75 ASSERT_TRUE(dl);
76 ASSERT_TRUE(
77 OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
78 ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
79 return true;
80 }));
81 }
82
83 TEST_P(InteropPlaygroundTest, CanDrawImage) {
84 auto compressed = LoadFixtureImageCompressed(
85 flutter::testing::OpenFixtureAsMapping("boston.jpg"));
86 ASSERT_NE(compressed, nullptr);
87 auto decompressed = compressed->Decode().ConvertToRGBA();
88 ASSERT_TRUE(decompressed.IsValid());
89 ImpellerMapping mapping = {};
90 mapping.data = decompressed.GetAllocation()->GetMapping();
91 mapping.length = decompressed.GetAllocation()->GetSize();
92
93 auto context = GetInteropContext();
94 ImpellerTextureDescriptor desc = {};
95 desc.pixel_format = ImpellerPixelFormat::kImpellerPixelFormatRGBA8888;
96 desc.size = {decompressed.GetSize().width, decompressed.GetSize().height};
97 desc.mip_count = 1u;
98 auto texture = Adopt<Texture>(ImpellerTextureCreateWithContentsNew(
99 context.GetC(), &desc, &mapping, nullptr));
100 ASSERT_TRUE(texture);
101 auto builder =
102 Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
103 ImpellerPoint point = {100, 100};
104 ImpellerDisplayListBuilderDrawTexture(builder.GetC(), texture.GetC(), &point,
105 kImpellerTextureSamplingLinear,
106 nullptr);
107 auto dl = Adopt<DisplayList>(
108 ImpellerDisplayListBuilderCreateDisplayListNew(builder.GetC()));
109 ASSERT_TRUE(
110 OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
111 ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
112 return true;
113 }));
114 }
115
116 TEST_P(InteropPlaygroundTest, CanCreateOpenGLImage) {
117 auto context = GetInteropContext();
118
119 auto impeller_context = context->GetContext();
120
121 if (impeller_context->GetBackendType() !=
122 impeller::Context::BackendType::kOpenGLES) {
123 GTEST_SKIP() << "This test works with OpenGL handles is only suitable for "
124 "that backend.";
125 return;
126 }
127
128 const auto& gl_context = ContextGLES::Cast(*impeller_context);
129 const auto& gl = gl_context.GetReactor()->GetProcTable();
130
131 constexpr ISize external_texture_size = {200, 300};
132
133 Allocation texture_data;
134 ASSERT_TRUE(
135 texture_data.Truncate(Bytes{external_texture_size.Area() * 4u}, false));
136
137 const auto kClearColor = Color::Fuchsia().ToR8G8B8A8();
138
139 for (size_t i = 0; i < external_texture_size.Area() * 4u; i += 4u) {
140 memcpy(texture_data.GetBuffer() + i, kClearColor.data(), 4);
141 }
142
143 GLuint external_texture = GL_NONE;
144 gl.GenTextures(1u, &external_texture);
145 ASSERT_NE(external_texture, 0u);
146 gl.BindTexture(GL_TEXTURE_2D, external_texture);
147 gl.TexImage2D(GL_TEXTURE_2D, //
148 0, //
149 GL_RGBA, //
150 external_texture_size.width, //
151 external_texture_size.height, //
152 0, //
153 GL_RGBA, //
154 GL_UNSIGNED_BYTE, //
155 texture_data.GetBuffer() //
156 );
157
158 ImpellerTextureDescriptor desc = {};
159 desc.pixel_format = ImpellerPixelFormat::kImpellerPixelFormatRGBA8888;
160 desc.size = {external_texture_size.width, external_texture_size.height};
161 desc.mip_count = 1u;
162 auto texture = Adopt<Texture>(ImpellerTextureCreateWithOpenGLTextureHandleNew(
163 context.GetC(), //
164 &desc, //
165 external_texture //
166 ));
167 ASSERT_TRUE(texture);
168
169 ASSERT_EQ(ImpellerTextureGetOpenGLHandle(texture.GetC()), external_texture);
170
171 auto builder =
172 Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
173 ImpellerPoint point = {100, 100};
174 ImpellerDisplayListBuilderDrawTexture(builder.GetC(), texture.GetC(), &point,
175 kImpellerTextureSamplingLinear,
176 nullptr);
177 auto dl = Adopt<DisplayList>(
178 ImpellerDisplayListBuilderCreateDisplayListNew(builder.GetC()));
179 ASSERT_TRUE(
180 OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
181 ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
182 return true;
183 }));
184 }
185
186 TEST_P(InteropPlaygroundTest, CanCreateParagraphs) {
187 // Create a typography context.
188 auto type_context = Adopt<TypographyContext>(ImpellerTypographyContextNew());
189 ASSERT_TRUE(type_context);
190
191 // Create a builder.
192 auto builder =
193 Adopt<ParagraphBuilder>(ImpellerParagraphBuilderNew(type_context.GetC()));
194 ASSERT_TRUE(builder);
195
196 // Create a paragraph style with the font size and foreground and background
197 // colors.
198 auto style = Adopt<ParagraphStyle>(ImpellerParagraphStyleNew());
199 ASSERT_TRUE(style);
200 ImpellerParagraphStyleSetFontSize(style.GetC(), 150.0f);
201
202 {
203 auto paint = Adopt<Paint>(ImpellerPaintNew());
204 ASSERT_TRUE(paint);
205 ImpellerColor color = {1.0, 0.0, 0.0, 1.0};
206 ImpellerPaintSetColor(paint.GetC(), &color);
207 ImpellerParagraphStyleSetForeground(style.GetC(), paint.GetC());
208 }
209
210 {
211 auto paint = Adopt<Paint>(ImpellerPaintNew());
212 ASSERT_TRUE(paint);
213 ImpellerColor color = {1.0, 1.0, 1.0, 1.0};
214 ImpellerPaintSetColor(paint.GetC(), &color);
215 ImpellerParagraphStyleSetBackground(style.GetC(), paint.GetC());
216 }
217
218 // Push the style onto the style stack.
219 ImpellerParagraphBuilderPushStyle(builder.GetC(), style.GetC());
220 std::string text = "the ⚡️ quick ⚡️ brown 🦊 fox jumps over the lazy dog 🐶.";
221
222 // Add the paragraph text data.
223 ImpellerParagraphBuilderAddText(builder.GetC(),
224 reinterpret_cast<const uint8_t*>(text.data()),
225 text.size());
226
227 // Layout and build the paragraph.
228 auto paragraph = Adopt<Paragraph>(
229 ImpellerParagraphBuilderBuildParagraphNew(builder.GetC(), 1200.0f));
230 ASSERT_TRUE(paragraph);
231
232 // Create a display list with just the paragraph drawn into it.
233 auto dl_builder =
234 Adopt<DisplayListBuilder>(ImpellerDisplayListBuilderNew(nullptr));
235 ImpellerPoint point = {20, 20};
236 ImpellerDisplayListBuilderDrawParagraph(dl_builder.GetC(), paragraph.GetC(),
237 &point);
238 auto dl = Adopt<DisplayList>(
239 ImpellerDisplayListBuilderCreateDisplayListNew(dl_builder.GetC()));
240
241 ASSERT_TRUE(
242 OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
243 ImpellerSurfaceDrawDisplayList(surface.GetC(), dl.GetC());
244 return true;
245 }));
246 }
247
248 } // namespace impeller::interop::testing
ImpellerPoint
Definition: impeller.h:241
impeller.h
ImpellerTextureDescriptor
Definition: impeller.h:279
dl.h
paragraph.h
surface.h
ImpellerMapping::length
uint64_t length
Definition: impeller.h:287
dl_builder.h
ImpellerTextureDescriptor::mip_count
uint32_t mip_count
Definition: impeller.h:282
impeller::interop::ImpellerParagraphBuilderNew
IMPELLER_EXTERN_C ImpellerParagraphBuilder ImpellerParagraphBuilderNew(ImpellerTypographyContext context)
Definition: impeller.cc:985
allocation.h
impeller::interop::ImpellerDisplayListBuilderRelease
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderRelease(ImpellerDisplayListBuilder builder)
Definition: impeller.cc:119
impeller::interop::ImpellerTextureCreateWithContentsNew
IMPELLER_EXTERN_C ImpellerTexture ImpellerTextureCreateWithContentsNew(ImpellerContext context, const ImpellerTextureDescriptor *descriptor, const ImpellerMapping *contents, void *contents_on_release_user_data)
Definition: impeller.cc:465
impeller::interop::testing
Definition: impeller_unittests.cc:22
impeller::interop::ImpellerTypographyContextNew
IMPELLER_EXTERN_C ImpellerTypographyContext ImpellerTypographyContextNew()
Definition: impeller.cc:1089
ImpellerISize
Definition: impeller.h:251
impeller::interop::testing::PlaygroundTest
Definition: playground_test.h:16
impeller::interop::ImpellerDisplayListBuilderGetTransform
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderGetTransform(ImpellerDisplayListBuilder builder, ImpellerMatrix *out_transform)
Definition: impeller.cc:171
ImpellerMapping
Definition: impeller.h:285
impeller::interop::ImpellerParagraphBuilderAddText
IMPELLER_EXTERN_C void ImpellerParagraphBuilderAddText(ImpellerParagraphBuilder paragraph_builder, const uint8_t *data, uint32_t length)
Definition: impeller.cc:1021
ImpellerColor
Definition: impeller.h:271
context_gles.h
ImpellerRect
Definition: impeller.h:234
impeller::interop::ImpellerParagraphStyleSetFontSize
IMPELLER_EXTERN_C void ImpellerParagraphStyleSetFontSize(ImpellerParagraphStyle paragraph_style, float size)
Definition: impeller.cc:941
impeller::interop::ImpellerDisplayListBuilderDrawTexture
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderDrawTexture(ImpellerDisplayListBuilder builder, ImpellerTexture texture, const ImpellerPoint *point, ImpellerTextureSampling sampling, ImpellerPaint paint)
Definition: impeller.cc:632
impeller::interop::ImpellerSurfaceCreateWrappedFBONew
IMPELLER_EXTERN_C ImpellerSurface ImpellerSurfaceCreateWrappedFBONew(ImpellerContext context, uint64_t fbo, ImpellerPixelFormat format, const ImpellerISize *size)
Definition: impeller.cc:604
impeller::interop::ImpellerDisplayListBuilderTranslate
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderTranslate(ImpellerDisplayListBuilder builder, float x_translation, float y_translation)
Definition: impeller.cc:158
impeller::Color::Fuchsia
static constexpr Color Fuchsia()
Definition: color.h:465
impeller::interop::ImpellerSurfaceDrawDisplayList
IMPELLER_EXTERN_C bool ImpellerSurfaceDrawDisplayList(ImpellerSurface surface, ImpellerDisplayList display_list)
Definition: impeller.cc:626
impeller::interop::ImpellerDisplayListBuilderRestore
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderRestore(ImpellerDisplayListBuilder builder)
Definition: impeller.cc:140
impeller::Allocation::Truncate
bool Truncate(Bytes length, bool npot=true)
Resize the underlying allocation to at least given number of bytes.
Definition: allocation.cc:32
paragraph_builder.h
typography_context.h
impeller::TSize
Definition: size.h:19
impeller::interop::ImpellerPaintSetColor
IMPELLER_EXTERN_C void ImpellerPaintSetColor(ImpellerPaint paint, const ImpellerColor *color)
Definition: impeller.cc:348
ImpellerMatrix
Definition: impeller.h:256
impeller::interop::ImpellerParagraphBuilderPushStyle
IMPELLER_EXTERN_C void ImpellerParagraphBuilderPushStyle(ImpellerParagraphBuilder paragraph_builder, ImpellerParagraphStyle style)
Definition: impeller.cc:1008
impeller::Context::BackendType::kOpenGLES
@ kOpenGLES
impeller::interop::ImpellerTextureCreateWithOpenGLTextureHandleNew
IMPELLER_EXTERN_C ImpellerTexture ImpellerTextureCreateWithOpenGLTextureHandleNew(ImpellerContext context, const ImpellerTextureDescriptor *descriptor, uint64_t external_gl_handle)
Definition: impeller.cc:509
kImpellerPixelFormatRGBA8888
@ kImpellerPixelFormatRGBA8888
Definition: impeller.h:172
impeller::interop::ImpellerDisplayListBuilderCreateDisplayListNew
IMPELLER_EXTERN_C ImpellerDisplayList ImpellerDisplayListBuilderCreateDisplayListNew(ImpellerDisplayListBuilder builder)
Definition: impeller.cc:586
impeller::interop::testing::TEST_P
TEST_P(InteropPlaygroundTest, CanCreateContext)
Definition: impeller_unittests.cc:27
impeller::interop::ImpellerDisplayListBuilderGetSaveCount
IMPELLER_EXTERN_C uint32_t ImpellerDisplayListBuilderGetSaveCount(ImpellerDisplayListBuilder builder)
Definition: impeller.cc:183
impeller::Color::ToR8G8B8A8
constexpr std::array< uint8_t, 4 > ToR8G8B8A8() const
Convert to R8G8B8A8 representation.
Definition: color.h:245
formats.h
texture.h
impeller::interop::ImpellerDisplayListBuilderDrawParagraph
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderDrawParagraph(ImpellerDisplayListBuilder builder, ImpellerParagraph paragraph, const ImpellerPoint *point)
Definition: impeller.cc:979
impeller::AllocationSize< 1u >
impeller::Allocation::GetBuffer
uint8_t * GetBuffer() const
Gets the pointer to the start of the allocation.
Definition: allocation.cc:20
playground_test.h
impeller::interop::ImpellerDisplayListBuilderNew
IMPELLER_EXTERN_C ImpellerDisplayListBuilder ImpellerDisplayListBuilderNew(const ImpellerRect *cull_rect)
Definition: impeller.cc:108
impeller::Allocation
Describes an allocation on the heap.
Definition: allocation.h:22
impeller::interop::ToImpellerType
constexpr Matrix ToImpellerType(const ImpellerMatrix &m)
Definition: formats.h:198
impeller::interop::testing::INSTANTIATE_OPENGLES_PLAYGROUND_SUITE
INSTANTIATE_OPENGLES_PLAYGROUND_SUITE(InteropPlaygroundTest)
impeller::interop::ImpellerDisplayListBuilderDrawRect
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderDrawRect(ImpellerDisplayListBuilder builder, const ImpellerRect *rect, ImpellerPaint paint)
Definition: impeller.cc:416
impeller::interop::ImpellerDisplayListBuilderSave
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderSave(ImpellerDisplayListBuilder builder)
Definition: impeller.cc:124
ImpellerTextureDescriptor::pixel_format
ImpellerPixelFormat pixel_format
Definition: impeller.h:280
paragraph_style.h
impeller::BackendCast< ContextGLES, Context >::Cast
static ContextGLES & Cast(Context &base)
Definition: backend_cast.h:13
kImpellerTextureSamplingLinear
@ kImpellerTextureSamplingLinear
Definition: impeller.h:177
impeller::interop::ImpellerParagraphStyleSetBackground
IMPELLER_EXTERN_C void ImpellerParagraphStyleSetBackground(ImpellerParagraphStyle paragraph_style, ImpellerPaint paint)
Definition: impeller.cc:909
impeller::interop::ImpellerTextureGetOpenGLHandle
IMPELLER_EXTERN_C uint64_t ImpellerTextureGetOpenGLHandle(ImpellerTexture texture)
Definition: impeller.cc:563
color
DlColor color
Definition: dl_golden_blur_unittests.cc:24
paint.h
ImpellerMapping::data
const uint8_t *IMPELLER_NONNULL data
Definition: impeller.h:286
ImpellerISize::width
int64_t width
Definition: impeller.h:252
impeller::interop::ImpellerParagraphStyleSetForeground
IMPELLER_EXTERN_C void ImpellerParagraphStyleSetForeground(ImpellerParagraphStyle paragraph_style, ImpellerPaint paint)
Definition: impeller.cc:904
impeller::interop::ImpellerParagraphStyleNew
IMPELLER_EXTERN_C ImpellerParagraphStyle ImpellerParagraphStyleNew()
Definition: impeller.cc:889
impeller::interop::ImpellerParagraphBuilderBuildParagraphNew
IMPELLER_EXTERN_C ImpellerParagraph ImpellerParagraphBuilderBuildParagraphNew(ImpellerParagraphBuilder paragraph_builder, float width)
Definition: impeller.cc:1033
ImpellerTextureDescriptor::size
ImpellerISize size
Definition: impeller.h:281
context.h
impeller::interop::ImpellerPaintNew
IMPELLER_EXTERN_C ImpellerPaint ImpellerPaintNew()
Definition: impeller.cc:333