Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
renderer_golden_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// Golden tests for the low-level renderer API. Unlike renderer_unittests.cc,
6// which opens an interactive playground, the tests here render through the
7// golden harness and have their output uploaded to Skia Gold. They only build
8// as part of the golden test executable.
9
10#include <array>
11#include <cstdint>
12#include <vector>
13
20#include "impeller/fixtures/baby.frag.h"
21#include "impeller/fixtures/baby.vert.h"
22#include "impeller/fixtures/instanced_attributes.frag.h"
23#include "impeller/fixtures/instanced_attributes.vert.h"
24#include "impeller/fixtures/mipmaps.frag.h"
25#include "impeller/fixtures/mipmaps.vert.h"
26#include "impeller/fixtures/texture.frag.h"
27#include "impeller/fixtures/texture.vert.h"
38
39// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
40// NOLINTBEGIN(bugprone-unchecked-optional-access)
41
42namespace impeller {
43namespace testing {
44
45#ifdef IMPELLER_GOLDEN_TESTS
46using RendererGoldenTest = GoldenPlaygroundTest;
47#else
49#endif
50
52
53// Ported from RendererTest.BabysFirstTriangle. Draws a single gradient
54// triangle straight through the renderer API. The shader's time uniform is
55// pinned to zero so the golden is deterministic.
56TEST_P(RendererGoldenTest, BabysFirstTriangle) {
57 using VS = BabyVertexShader;
58 using FS = BabyFragmentShader;
59
60 std::shared_ptr<Context> context = GetContext();
61 ASSERT_TRUE(context);
62
64 ASSERT_TRUE(desc.has_value());
65 ASSERT_TRUE(InitializePipelineDescriptorForRendering(*desc));
66 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
67 ASSERT_TRUE(pipeline);
68
69 VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
70 vertex_buffer_builder.AddVertices({
71 {{-0.5, -0.5}, Color::Red(), Color::Green()},
72 {{0.0, 0.5}, Color::Green(), Color::Blue()},
73 {{0.5, -0.5}, Color::Blue(), Color::Red()},
74 });
75 auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
76 *context->GetResourceAllocator());
77
78 auto host_buffer = HostBuffer::Create(
79 context->GetResourceAllocator(), context->GetIdleWaiter(),
80 context->GetCapabilities()->GetMinimumUniformAlignment());
81
82 ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
83 // The harness runs the callback once per pass; start each from a clean
84 // host buffer.
85 host_buffer->Reset();
87 pass.SetVertexBuffer(vertex_buffer);
88
89 FS::FragInfo frag_info;
90 frag_info.time = 0.0f;
91 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
92
93 return pass.Draw().ok();
94 }));
95}
96
97// Ported from RendererTest.CanRenderInstancedWithVertexAttributes. Renders an
98// instanced draw whose per-instance data arrives through an instance-rate
99// vertex buffer binding rather than an instance-ID builtin. This is the only
100// portable instancing mechanism on OpenGL ES. Per-instance offsets and colors
101// are fixed so the golden is deterministic.
102TEST_P(RendererGoldenTest, CanRenderInstancedWithVertexAttributes) {
103 using VS = InstancedAttributesVertexShader;
104 using FS = InstancedAttributesFragmentShader;
105
106 std::shared_ptr<Context> context = GetContext();
107 ASSERT_TRUE(context);
108
110 ASSERT_TRUE(desc.has_value());
111 ASSERT_TRUE(InitializePipelineDescriptorForRendering(*desc));
112
113 // Per-instance data is laid out contiguously, one record per instance.
114 struct InstanceData {
115 Vector2 offset;
116 Vector4 color;
117 };
118
119 // Two vertex bindings: binding 0 carries per-vertex geometry and advances
120 // once per vertex; binding 1 carries per-instance data and advances once
121 // per instance.
122 auto vertex_desc = std::make_shared<VertexDescriptor>();
123 ShaderStageIOSlot position_slot = VS::kInputVertexPosition;
124 ShaderStageIOSlot offset_slot = VS::kInputInstanceOffset;
125 ShaderStageIOSlot color_slot = VS::kInputInstanceColor;
126 position_slot.binding = 0;
127 position_slot.offset = 0;
128 offset_slot.binding = 1;
129 offset_slot.offset = offsetof(InstanceData, offset);
130 color_slot.binding = 1;
131 color_slot.offset = offsetof(InstanceData, color);
132 const std::vector<ShaderStageIOSlot> io_slots = {position_slot, offset_slot,
133 color_slot};
134 const std::vector<ShaderStageBufferLayout> layouts = {
136 .binding = 0,
137 .input_rate = VertexInputRate::kVertex},
138 ShaderStageBufferLayout{.stride = sizeof(InstanceData),
139 .binding = 1,
140 .input_rate = VertexInputRate::kInstance},
141 };
142 vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
143 vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
144 vertex_desc->SetStageInputs(io_slots, layouts);
145 desc->SetVertexDescriptor(std::move(vertex_desc));
146 auto pipeline =
147 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
148 ASSERT_TRUE(pipeline);
149
150 // A single triangle, drawn once per instance.
151 std::array<Vector2, 3> geometry = {
152 Vector2{0, 0},
153 Vector2{0, 100},
154 Vector2{100, 0},
155 };
156
157 static constexpr size_t kInstanceCount = 4u;
158 std::array<InstanceData, kInstanceCount> instances = {
159 InstanceData{Vector2{0, 0}, Vector4{1, 0, 0, 1}},
160 InstanceData{Vector2{120, 0}, Vector4{0, 1, 0, 1}},
161 InstanceData{Vector2{0, 120}, Vector4{0, 0, 1, 1}},
162 InstanceData{Vector2{120, 120}, Vector4{1, 1, 0, 1}},
163 };
164
165 auto geometry_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
166 reinterpret_cast<uint8_t*>(geometry.data()),
167 geometry.size() * sizeof(Vector2));
168 auto instance_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
169 reinterpret_cast<uint8_t*>(instances.data()),
170 instances.size() * sizeof(InstanceData));
171 ASSERT_TRUE(geometry_buffer && instance_buffer);
172
173 auto host_buffer = HostBuffer::Create(
174 context->GetResourceAllocator(), context->GetIdleWaiter(),
175 context->GetCapabilities()->GetMinimumUniformAlignment());
176
177 ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
178 // The harness runs the callback once per pass; start each from a clean
179 // host buffer.
180 host_buffer->Reset();
181 pass.SetCommandLabel("InstancedAttributes");
182 pass.SetPipeline(pipeline);
183
184 std::array<BufferView, 2> vertex_buffers = {
185 BufferView(geometry_buffer,
186 Range(0, geometry.size() * sizeof(Vector2))),
187 BufferView(instance_buffer,
188 Range(0, instances.size() * sizeof(InstanceData))),
189 };
190 pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
191 pass.SetElementCount(geometry.size());
192 pass.SetInstanceCount(kInstanceCount);
193
194 VS::FrameInfo frame_info;
195 frame_info.mvp =
196 pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
197 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
198
199 return pass.Draw().ok();
200 }));
201}
202
203// Samples a sample-only block-compressed texture across a fullscreen quad
204// through the golden harness. The pixel format and the raw block bytes are the
205// only things that differ between the compressed families; the texture upload,
206// pipeline, quad, and draw are shared by every compressed-format golden below.
208 PixelFormat format,
209 const std::vector<uint8_t>& block_data,
210 ISize size) {
211 using VS = TextureVertexShader;
212 using FS = TextureFragmentShader;
213
214 std::shared_ptr<Context> context = test.GetContext();
215 ASSERT_TRUE(context);
216
217 TextureDescriptor texture_desc;
219 texture_desc.format = format;
220 texture_desc.size = size;
221 texture_desc.mip_count = 1u;
222 texture_desc.usage = TextureUsage::kShaderRead;
223 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
224 ASSERT_TRUE(texture);
225 ASSERT_TRUE(texture->SetContents(block_data.data(), block_data.size()));
226
228 ASSERT_TRUE(desc.has_value());
229 ASSERT_TRUE(test.InitializePipelineDescriptorForRendering(*desc));
230 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
231 ASSERT_TRUE(pipeline);
232
233 // A fullscreen quad in normalized device coordinates with an identity MVP.
234 VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
235 vertex_buffer_builder.AddVertices({
236 {{-1, -1, 0.0}, {0.0, 0.0}},
237 {{1, -1, 0.0}, {1.0, 0.0}},
238 {{1, 1, 0.0}, {1.0, 1.0}},
239 {{-1, -1, 0.0}, {0.0, 0.0}},
240 {{1, 1, 0.0}, {1.0, 1.0}},
241 {{-1, 1, 0.0}, {0.0, 1.0}},
242 });
243 auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
244 *context->GetResourceAllocator());
245
246 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
247
248 auto host_buffer = HostBuffer::Create(
249 context->GetResourceAllocator(), context->GetIdleWaiter(),
250 context->GetCapabilities()->GetMinimumUniformAlignment());
251
252 ASSERT_TRUE(test.OpenPlaygroundHere([&](RenderPass& pass) -> bool {
253 host_buffer->Reset();
254 pass.SetPipeline(pipeline);
255 pass.SetVertexBuffer(vertex_buffer);
256
257 VS::UniformBuffer uniforms;
258 uniforms.mvp = Matrix();
259 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
260 FS::BindTextureContents(pass, texture, sampler);
261
262 return pass.Draw().ok();
263 }));
264}
265
266// Uploads a block-compressed (BC1/DXT1) texture and samples it onto a
267// fullscreen quad. The texture is an 8x8 image laid out as a 2x2 grid of solid
268// color blocks, so the golden is four colored quadrants. BC1 is the most widely
269// supported compressed family on desktop GPUs; backends without it are skipped.
270TEST_P(RendererGoldenTest, CanRenderBC1CompressedTexture) {
271 std::shared_ptr<Context> context = GetContext();
272 ASSERT_TRUE(context);
273 if (!context->GetCapabilities()->SupportsTextureCompression(
275 GTEST_SKIP() << "Backend does not support BC texture compression.";
276 }
277
278 // A solid-color BC1 block stores the color in both RGB565 endpoints with
279 // all-zero selector bits, which decodes to a single opaque color.
280 auto bc1_solid_block = [](uint16_t rgb565) -> std::array<uint8_t, 8> {
281 const auto lo = static_cast<uint8_t>(rgb565 & 0xFF);
282 const auto hi = static_cast<uint8_t>(rgb565 >> 8);
283 return {{lo, hi, lo, hi, 0, 0, 0, 0}};
284 };
285 // RGB565: red, green, blue, white.
286 const std::array<std::array<uint8_t, 8>, 4> blocks = {
287 {bc1_solid_block(0xF800), bc1_solid_block(0x07E0),
288 bc1_solid_block(0x001F), bc1_solid_block(0xFFFF)}};
289 std::vector<uint8_t> data;
290 for (const auto& block : blocks) {
291 data.insert(data.end(), block.begin(), block.end());
292 }
293
295 ISize{8, 8});
296}
297
298// Uploads an ETC2 RGB8 texture and samples it onto a fullscreen quad. ETC2 is
299// the standard compressed family on OpenGL ES 3.0 and mobile GPUs; backends
300// without it are skipped. The 8x8 image is a 2x2 grid of solid color blocks, so
301// the golden is the same four colored quadrants as the BC1 and ASTC goldens.
302TEST_P(RendererGoldenTest, CanRenderETC2CompressedTexture) {
303 std::shared_ptr<Context> context = GetContext();
304 ASSERT_TRUE(context);
305 if (!context->GetCapabilities()->SupportsTextureCompression(
307 GTEST_SKIP() << "Backend does not support ETC2 texture compression.";
308 }
309
310 // A solid-color ETC2 RGB8 block in "individual" mode (differential bit 0,
311 // which decodes like ETC1). The 64-bit block is laid out big-endian (byte 0
312 // most significant): byte 0 = R nibbles (R1,R2), byte 1 = G, byte 2 = B,
313 // byte 3 = codeword/diff/flip bits (all 0), bytes 4..7 = the two pixel-index
314 // bit planes. Both sub-blocks share the base color and every texel uses index
315 // 0 (all-zero planes), so the block is one flat color.
316 auto etc2_solid_block = [](uint8_t r, uint8_t g,
317 uint8_t b) -> std::array<uint8_t, 8> {
318 return {{r, g, b, 0x00, 0x00, 0x00, 0x00, 0x00}};
319 };
320 // Red, green, blue, white. Each channel byte is 0xFF (nibble 0xF, ~255) or
321 // 0x00.
322 const std::array<std::array<uint8_t, 8>, 4> blocks = {
323 {etc2_solid_block(0xFF, 0x00, 0x00), etc2_solid_block(0x00, 0xFF, 0x00),
324 etc2_solid_block(0x00, 0x00, 0xFF), etc2_solid_block(0xFF, 0xFF, 0xFF)}};
325 std::vector<uint8_t> data;
326 for (const auto& block : blocks) {
327 data.insert(data.end(), block.begin(), block.end());
328 }
329
331 ISize{8, 8});
332}
333
334// Uploads an ASTC 4x4 LDR texture and samples it onto a fullscreen quad. ASTC
335// is common on modern mobile and some desktop GPUs; backends without it are
336// skipped. The 8x8 image is a 2x2 grid of solid color blocks, so the golden is
337// the same four colored quadrants as the BC1 and ETC2 goldens.
338TEST_P(RendererGoldenTest, CanRenderASTCCompressedTexture) {
339 std::shared_ptr<Context> context = GetContext();
340 ASSERT_TRUE(context);
341 if (!context->GetCapabilities()->SupportsTextureCompression(
343 GTEST_SKIP() << "Backend does not support ASTC texture compression.";
344 }
345
346 // An ASTC void-extent block encodes one constant color directly: the 0xFC
347 // 0xFD header marks a 2D LDR void-extent with the "no extent" sentinel
348 // coordinates (all ones), followed by four little-endian UNORM16 channels
349 // (R, G, B, A). Alpha is opaque.
350 auto astc_solid_block = [](uint16_t r, uint16_t g,
351 uint16_t b) -> std::array<uint8_t, 16> {
352 return {{0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
353 static_cast<uint8_t>(r & 0xFF), static_cast<uint8_t>(r >> 8),
354 static_cast<uint8_t>(g & 0xFF), static_cast<uint8_t>(g >> 8),
355 static_cast<uint8_t>(b & 0xFF), static_cast<uint8_t>(b >> 8), 0xFF,
356 0xFF}};
357 };
358 // Red, green, blue, white.
359 const std::array<std::array<uint8_t, 16>, 4> blocks = {
360 {astc_solid_block(0xFFFF, 0, 0), astc_solid_block(0, 0xFFFF, 0),
361 astc_solid_block(0, 0, 0xFFFF),
362 astc_solid_block(0xFFFF, 0xFFFF, 0xFFFF)}};
363 std::vector<uint8_t> data;
364 for (const auto& block : blocks) {
365 data.insert(data.end(), block.begin(), block.end());
366 }
367
369 ISize{8, 8});
370}
371
372// Samples a texture whose mip chain was populated by hand (the base level via
373// SetContents, the 4x4 second level via a blit copy) rather than by the
374// GenerateMipmap blit, then samples it at the given LOD. Such a texture has
375// mip_count > 1 with NeedsMipmapGeneration() == true; sampling it used to fail
376// the (now-removed) bind-time mipmap validation on desktop Metal and OpenGL ES,
377// so the golden would have been blank there. The base is four colored quadrants
378// and the second level is solid orange, so LOD 0 renders the quadrants and LOD
379// 1 renders solid orange.
381 float lod) {
382 using VS = MipmapsVertexShader;
383 using FS = MipmapsFragmentShader;
384
385 std::shared_ptr<Context> context = test.GetContext();
386 ASSERT_TRUE(context);
387
388 TextureDescriptor texture_desc;
391 texture_desc.size = ISize{8, 8};
392 texture_desc.mip_count = 2u; // base 8x8 + one 4x4 mip; populated by hand.
393 texture_desc.usage = TextureUsage::kShaderRead;
394 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
395 ASSERT_TRUE(texture);
396
397 // Base level: a 2x2 grid of red/green/blue/white quadrants.
398 std::vector<uint8_t> base_data(8 * 8 * 4);
399 for (int y = 0; y < 8; ++y) {
400 for (int x = 0; x < 8; ++x) {
401 const size_t i = (static_cast<size_t>(y) * 8 + x) * 4;
402 const bool right = x >= 4;
403 const bool bottom = y >= 4;
404 uint8_t r = 0, g = 0, b = 0;
405 if (!right && !bottom) {
406 r = 0xFF; // top-left: red.
407 } else if (right && !bottom) {
408 g = 0xFF; // top-right: green.
409 } else if (!right && bottom) {
410 b = 0xFF; // bottom-left: blue.
411 } else {
412 r = g = b = 0xFF; // bottom-right: white.
413 }
414 base_data[i] = r;
415 base_data[i + 1] = g;
416 base_data[i + 2] = b;
417 base_data[i + 3] = 0xFF;
418 }
419 }
420 ASSERT_TRUE(texture->SetContents(base_data.data(), base_data.size()));
421
422 // Second level (4x4), solid orange so it is distinct from the base and from
423 // an empty level. Uploaded by hand via a blit copy rather than the
424 // GenerateMipmap blit, which keeps NeedsMipmapGeneration() true. This
425 // initializes the whole mip chain so the texture is complete on backends
426 // that require it (OpenGL ES samples a mipmapped texture as incomplete
427 // otherwise).
428 std::vector<uint8_t> mip_data(4 * 4 * 4);
429 for (size_t i = 0; i < mip_data.size(); i += 4) {
430 mip_data[i] = 0xFF; // r
431 mip_data[i + 1] = 0x80; // g
432 mip_data[i + 2] = 0x00; // b
433 mip_data[i + 3] = 0xFF; // a
434 }
435 auto mip_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
436 mip_data.data(), mip_data.size());
437 ASSERT_TRUE(mip_buffer);
438 auto cmd_buffer = context->CreateCommandBuffer();
439 ASSERT_TRUE(cmd_buffer);
440 auto blit_pass = cmd_buffer->CreateBlitPass();
441 ASSERT_TRUE(blit_pass);
442 // The destination region must match the 4x4 second level, not the 8x8 base,
443 // or the copy size check rejects the smaller source buffer.
444 ASSERT_TRUE(
445 blit_pass->AddCopy(DeviceBuffer::AsBufferView(mip_buffer), texture,
446 /*destination_region=*/IRect::MakeSize(ISize{4, 4}),
447 /*label=*/"Upload mip 1", /*mip_level=*/1u));
448 ASSERT_TRUE(blit_pass->EncodeCommands());
449 ASSERT_TRUE(context->GetCommandQueue()->Submit({cmd_buffer}).ok());
450
452 ASSERT_TRUE(desc.has_value());
453 ASSERT_TRUE(test.InitializePipelineDescriptorForRendering(*desc));
454 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
455 ASSERT_TRUE(pipeline);
456
457 // A fullscreen quad in normalized device coordinates with an identity MVP.
458 VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
459 vertex_buffer_builder.AddVertices({
460 {{-1, -1}, {0.0, 0.0}},
461 {{1, -1}, {1.0, 0.0}},
462 {{1, 1}, {1.0, 1.0}},
463 {{-1, -1}, {0.0, 0.0}},
464 {{1, 1}, {1.0, 1.0}},
465 {{-1, 1}, {0.0, 1.0}},
466 });
467 auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
468 *context->GetResourceAllocator());
469
470 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
471
472 auto host_buffer = HostBuffer::Create(
473 context->GetResourceAllocator(), context->GetIdleWaiter(),
474 context->GetCapabilities()->GetMinimumUniformAlignment());
475
476 ASSERT_TRUE(test.OpenPlaygroundHere([&](RenderPass& pass) -> bool {
477 host_buffer->Reset();
478 pass.SetPipeline(pipeline);
479 pass.SetVertexBuffer(vertex_buffer);
480
481 VS::FrameInfo frame_info;
482 frame_info.mvp = Matrix();
483 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
484
485 FS::FragInfo frag_info;
486 frag_info.lod = lod;
487 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
488
489 FS::BindTex(pass, texture, sampler);
490
491 return pass.Draw().ok();
492 }));
493}
494
495// LOD 0 reads the base level, so the golden is the four colored quadrants.
496TEST_P(RendererGoldenTest, CanSampleManuallyMippedTexture) {
497 DrawManuallyMippedTextureGolden(*this, /*lod=*/0.0f);
498}
499
500// LOD 1 reads the hand-uploaded second level, so the golden is solid orange.
501TEST_P(RendererGoldenTest, CanSampleManuallyMippedTextureLod1) {
502 DrawManuallyMippedTextureGolden(*this, /*lod=*/1.0f);
503}
504
505} // namespace testing
506} // namespace impeller
507
508// NOLINTEND(bugprone-unchecked-optional-access)
bool ok() const
Definition status.h:71
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
static std::shared_ptr< HostBuffer > Create(const std::shared_ptr< Allocator > &allocator, const std::shared_ptr< const IdleWaiter > &idle_waiter, size_t minimum_uniform_alignment, std::shared_ptr< const GpuSubmissionTracker > submission_tracker=nullptr)
bool OpenPlaygroundHere(const RenderCallback &render_callback)
bool InitializePipelineDescriptorForRendering(PipelineDescriptor &desc) const
Initializes the provided |PipelineDescriptor| with appropriate default values to match the conditions...
std::shared_ptr< Context > GetContext() const
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition render_pass.h:30
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
const Matrix & GetOrthographicTransform() const
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
virtual void SetInstanceCount(size_t count)
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetElementCount(size_t count)
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
VertexBuffer CreateVertexBuffer(HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer) const
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
int32_t x
uint32_t uint32_t * format
FlTexture * texture
double y
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
static void DrawCompressedTextureGolden(RendererGoldenTest &test, PixelFormat format, const std::vector< uint8_t > &block_data, ISize size)
TEST_P(AiksTest, DrawAtlasNoColor)
PlaygroundTestWithGoldens RendererGoldenTest
static void DrawManuallyMippedTextureGolden(RendererGoldenTest &test, float lod)
Point Vector2
Definition point.h:430
@ kInstance
The binding is read once per instance.
@ kVertex
The binding is read once per vertex. This is the default.
GlyphAtlasPipeline::VertexShader VS
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition formats.h:99
@ kBC
S3TC, RGTC, and BPTC (BC1 through BC7). Desktop GPUs.
@ kETC2
ETC2 and EAC. Mobile, OpenGL ES 3.0, and WebGL2.
@ kASTC
ASTC LDR. Modern mobile and some desktop.
GlyphAtlasPipeline::FragmentShader FS
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
std::shared_ptr< ContextGLES > context
std::shared_ptr< PipelineGLES > pipeline
static constexpr Color Red()
Definition color.h:277
static constexpr Color Blue()
Definition color.h:281
static constexpr Color Green()
Definition color.h:279
static constexpr Matrix MakeScale(const Vector3 &s)
Definition matrix.h:104
static std::optional< PipelineDescriptor > MakeDefaultPipelineDescriptor(const Context &context, const std::vector< Scalar > &constants={})
Create a default pipeline descriptor using the combination reflected shader information....
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:150
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...