5#include "flutter/fml/logging.h"
6#include "flutter/fml/time/time_point.h"
11#include "impeller/fixtures/array.frag.h"
12#include "impeller/fixtures/array.vert.h"
13#include "impeller/fixtures/baby.frag.h"
14#include "impeller/fixtures/baby.vert.h"
15#include "impeller/fixtures/box_fade.frag.h"
16#include "impeller/fixtures/box_fade.vert.h"
17#include "impeller/fixtures/colors.frag.h"
18#include "impeller/fixtures/colors.vert.h"
19#include "impeller/fixtures/impeller.frag.h"
20#include "impeller/fixtures/impeller.vert.h"
21#include "impeller/fixtures/inactive_uniforms.frag.h"
22#include "impeller/fixtures/inactive_uniforms.vert.h"
23#include "impeller/fixtures/instanced_draw.frag.h"
24#include "impeller/fixtures/instanced_draw.vert.h"
25#include "impeller/fixtures/mipmaps.frag.h"
26#include "impeller/fixtures/mipmaps.vert.h"
27#include "impeller/fixtures/planet.frag.h"
28#include "impeller/fixtures/planet.vert.h"
29#include "impeller/fixtures/sepia.frag.h"
30#include "impeller/fixtures/sepia.vert.h"
31#include "impeller/fixtures/swizzle.frag.h"
32#include "impeller/fixtures/texture.frag.h"
33#include "impeller/fixtures/texture.vert.h"
43#include "third_party/imgui/imgui.h"
55 using VS = BoxFadeVertexShader;
56 using FS = BoxFadeFragmentShader;
60 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
61 ASSERT_TRUE(
desc.has_value());
63 desc->SetStencilAttachmentDescriptors(std::nullopt);
69 {{100, 100, 0.0}, {0.0, 0.0}},
70 {{800, 100, 0.0}, {1.0, 0.0}},
71 {{800, 800, 0.0}, {1.0, 1.0}},
72 {{100, 100, 0.0}, {0.0, 0.0}},
73 {{800, 800, 0.0}, {1.0, 1.0}},
74 {{100, 800, 0.0}, {0.0, 1.0}},
76 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
77 auto boston = CreateTextureForFixture(
"boston.jpg");
78 ASSERT_TRUE(bridge && boston);
79 const std::unique_ptr<const Sampler>& sampler =
80 context->GetSamplerLibrary()->GetSampler({});
85 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
86 static bool wireframe;
87 ImGui::Checkbox(
"Wireframe", &wireframe);
91 auto pipeline = context->GetPipelineLibrary()->GetPipeline(
desc).Get();
93 assert(pipeline && pipeline->IsValid());
95 pass.SetCommandLabel(
"Box");
96 pass.SetPipeline(pipeline);
100 VS::UniformBuffer uniforms;
101 EXPECT_EQ(pass.GetOrthographicTransform(),
105 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
107 FS::FrameInfo frame_info;
108 frame_info.current_time = GetSecondsElapsed();
109 frame_info.cursor_position = GetCursorPosition();
110 frame_info.window_size.x = GetWindowSize().width;
111 frame_info.window_size.y = GetWindowSize().height;
113 FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
114 FS::BindContents1(pass, boston, sampler);
115 FS::BindContents2(pass, bridge, sampler);
117 host_buffer->Reset();
118 return pass.Draw().ok();
125 ASSERT_TRUE(context);
128 using VS = BabyVertexShader;
129 using FS = BabyFragmentShader;
137 ASSERT_TRUE(
desc.has_value());
141 desc->SetStencilAttachmentDescriptors(std::nullopt);
145 auto pipeline = context->GetPipelineLibrary()->GetPipeline(
desc).Get();
159 *context->GetResourceAllocator());
162 pass.SetPipeline(pipeline);
163 pass.SetVertexBuffer(vertex_buffer);
165 FS::FragInfo frag_info;
169 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
171 return pass.Draw().ok();
177 using VS = ColorsVertexShader;
178 using FS = ColorsFragmentShader;
180 ASSERT_TRUE(context);
182 ASSERT_TRUE(
desc.has_value());
186 desc->SetStencilAttachmentDescriptors(std::nullopt);
188 context->GetPipelineLibrary()->GetPipeline(std::move(
desc)).Get();
189 ASSERT_TRUE(pipeline);
192 VS::PerVertexData vertices[8] = {
204 uint16_t indices[36] = {
216 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
217 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
220 .range =
Range(offsetof(Cube, vertices),
sizeof(Cube::vertices))};
223 .range =
Range(offsetof(Cube, indices),
sizeof(Cube::indices))};
228 const std::unique_ptr<const Sampler>& sampler =
229 context->GetSamplerLibrary()->GetSampler({});
230 ASSERT_TRUE(sampler);
238 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
239 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
240 ImGui::SliderFloat(
"Camera distance", &
distance, 0, 30);
243 pass.SetCommandLabel(
"Perspective Cube");
244 pass.SetPipeline(pipeline);
245 pass.SetVertexBuffer(vertex_buffer);
247 VS::UniformBuffer uniforms;
257 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
259 host_buffer->Reset();
260 return pass.Draw().ok();
266 using VS = BoxFadeVertexShader;
267 using FS = BoxFadeFragmentShader;
269 ASSERT_TRUE(context);
271 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
272 ASSERT_TRUE(
desc.has_value());
274 desc->SetStencilAttachmentDescriptors(std::nullopt);
276 context->GetPipelineLibrary()->GetPipeline(std::move(
desc)).Get();
277 ASSERT_TRUE(box_pipeline);
283 {{100, 100, 0.0}, {0.0, 0.0}},
284 {{800, 100, 0.0}, {1.0, 0.0}},
285 {{800, 800, 0.0}, {1.0, 1.0}},
286 {{100, 100, 0.0}, {0.0, 0.0}},
287 {{800, 800, 0.0}, {1.0, 1.0}},
288 {{100, 800, 0.0}, {0.0, 1.0}},
292 ASSERT_TRUE(vertex_buffer);
294 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
295 auto boston = CreateTextureForFixture(
"boston.jpg");
296 ASSERT_TRUE(bridge && boston);
297 const std::unique_ptr<const Sampler>& sampler =
298 context->GetSamplerLibrary()->GetSampler({});
299 ASSERT_TRUE(sampler);
303 for (
size_t i = 0;
i < 1;
i++) {
304 for (
size_t j = 0; j < 1; j++) {
305 pass.SetCommandLabel(
"Box");
306 pass.SetPipeline(box_pipeline);
307 pass.SetVertexBuffer(vertex_buffer);
309 FS::FrameInfo frame_info;
310 frame_info.current_time = GetSecondsElapsed();
311 frame_info.cursor_position = GetCursorPosition();
312 frame_info.window_size.x = GetWindowSize().width;
313 frame_info.window_size.y = GetWindowSize().height;
315 FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
316 FS::BindContents1(pass, boston, sampler);
317 FS::BindContents2(pass, bridge, sampler);
319 VS::UniformBuffer uniforms;
320 EXPECT_EQ(pass.GetOrthographicTransform(),
322 uniforms.mvp = pass.GetOrthographicTransform() *
325 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
326 if (!pass.Draw().ok()) {
332 host_buffer->Reset();
339 using VS = BoxFadeVertexShader;
340 using FS = BoxFadeFragmentShader;
342 ASSERT_TRUE(context);
345 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
347 pipeline_desc->ClearDepthAttachment();
350 ASSERT_TRUE(pipeline_desc.has_value());
352 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
353 ASSERT_TRUE(box_pipeline);
359 {{100, 100, 0.0}, {0.0, 0.0}},
360 {{800, 100, 0.0}, {1.0, 0.0}},
361 {{800, 800, 0.0}, {1.0, 1.0}},
362 {{100, 100, 0.0}, {0.0, 0.0}},
363 {{800, 800, 0.0}, {1.0, 1.0}},
364 {{100, 800, 0.0}, {0.0, 1.0}},
368 ASSERT_TRUE(vertex_buffer);
370 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
371 auto boston = CreateTextureForFixture(
"boston.jpg");
372 ASSERT_TRUE(bridge && boston);
373 const std::unique_ptr<const Sampler>& sampler =
374 context->GetSamplerLibrary()->GetSampler({});
375 ASSERT_TRUE(sampler);
377 std::shared_ptr<RenderPass> r2t_pass;
378 auto cmd_buffer = context->CreateCommandBuffer();
379 ASSERT_TRUE(cmd_buffer);
386 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
387 texture_descriptor.
format =
388 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
390 texture_descriptor.
size = {400, 400};
395 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
399 color0.
texture->SetLabel(
"r2t_target");
406 stencil_texture_desc.
size = texture_descriptor.
size;
410 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
415 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
416 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
419 r2t_pass->SetCommandLabel(
"Box");
420 r2t_pass->SetPipeline(box_pipeline);
421 r2t_pass->SetVertexBuffer(vertex_buffer);
423 FS::FrameInfo frame_info;
424 frame_info.current_time = GetSecondsElapsed();
425 frame_info.cursor_position = GetCursorPosition();
426 frame_info.window_size.x = GetWindowSize().width;
427 frame_info.window_size.y = GetWindowSize().height;
429 FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
430 FS::BindContents1(*r2t_pass, boston, sampler);
431 FS::BindContents2(*r2t_pass, bridge, sampler);
433 VS::UniformBuffer uniforms;
436 VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
437 ASSERT_TRUE(r2t_pass->Draw().ok());
438 ASSERT_TRUE(r2t_pass->EncodeCommands());
443 GTEST_SKIP_(
"Instancing is not supported on OpenGL.");
445 using VS = InstancedDrawVertexShader;
446 using FS = InstancedDrawFragmentShader;
450 VS::PerVertexData{
Point{10, 10}},
451 VS::PerVertexData{
Point{10, 110}},
452 VS::PerVertexData{
Point{110, 10}},
453 VS::PerVertexData{
Point{10, 110}},
454 VS::PerVertexData{
Point{110, 10}},
455 VS::PerVertexData{
Point{110, 110}},
461 ->GetPipelineLibrary()
465 .SetStencilAttachmentDescriptors(std::nullopt))
468 ASSERT_TRUE(pipeline && pipeline->IsValid());
470 static constexpr size_t kInstancesCount = 5u;
471 VS::InstanceInfo<kInstancesCount> instances;
472 for (
size_t i = 0;
i < kInstancesCount;
i++) {
477 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
481 VS::FrameInfo frame_info;
486 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
487 VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
493 host_buffer->Reset();
500 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
503 ASSERT_TRUE(context);
505 using VS = MipmapsVertexShader;
506 using FS = MipmapsFragmentShader;
508 ASSERT_TRUE(
desc.has_value());
510 desc->SetStencilAttachmentDescriptors(std::nullopt);
511 auto mipmaps_pipeline =
512 context->GetPipelineLibrary()->GetPipeline(std::move(
desc)).Get();
513 ASSERT_TRUE(mipmaps_pipeline);
518 texture_desc.
size = {800, 600};
521 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
524 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
525 auto boston = CreateTextureForFixture(
"boston.jpg");
526 ASSERT_TRUE(bridge && boston);
527 const std::unique_ptr<const Sampler>& sampler =
528 context->GetSamplerLibrary()->GetSampler({});
529 ASSERT_TRUE(sampler);
536 {{0, 0}, {0.0, 0.0}},
537 {{
size.x, 0}, {1.0, 0.0}},
539 {{0, 0}, {0.0, 0.0}},
541 {{0,
size.y}, {0.0, 1.0}},
545 ASSERT_TRUE(vertex_buffer);
549 auto buffer = context->CreateCommandBuffer();
553 buffer->SetLabel(
"Playground Command Buffer");
556 auto pass =
buffer->CreateBlitPass();
560 pass->SetLabel(
"Playground Blit Pass");
562 if (render_target.GetColorAttachments().empty()) {
567 pass->AddCopy(bridge,
texture);
569 if (!pass->EncodeCommands(context->GetResourceAllocator())) {
575 auto pass =
buffer->CreateRenderPass(render_target);
579 pass->SetLabel(
"Playground Render Pass");
581 pass->SetCommandLabel(
"Image");
582 pass->SetPipeline(mipmaps_pipeline);
583 pass->SetVertexBuffer(vertex_buffer);
585 VS::FrameInfo frame_info;
586 EXPECT_EQ(pass->GetOrthographicTransform(),
588 frame_info.mvp = pass->GetOrthographicTransform() *
590 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
592 FS::FragInfo frag_info;
594 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
596 auto& sampler = context->GetSamplerLibrary()->GetSampler({});
597 FS::BindTex(*pass,
texture, sampler);
601 pass->EncodeCommands();
604 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
607 host_buffer->Reset();
615 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
618 ASSERT_TRUE(context);
620 using VS = MipmapsVertexShader;
621 using FS = MipmapsFragmentShader;
623 ASSERT_TRUE(
desc.has_value());
625 desc->SetStencilAttachmentDescriptors(std::nullopt);
626 auto mipmaps_pipeline =
627 context->GetPipelineLibrary()->GetPipeline(std::move(
desc)).Get();
628 ASSERT_TRUE(mipmaps_pipeline);
630 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
631 auto boston = CreateTextureForFixture(
"boston.jpg");
632 ASSERT_TRUE(bridge && boston);
633 const std::unique_ptr<const Sampler>& sampler =
634 context->GetSamplerLibrary()->GetSampler({});
635 ASSERT_TRUE(sampler);
640 texture_desc.
size = bridge->GetTextureDescriptor().size;
646 device_buffer_desc.
size =
647 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
649 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
656 {{0, 0}, {0.0, 0.0}},
657 {{
size.x, 0}, {1.0, 0.0}},
659 {{0, 0}, {0.0, 0.0}},
661 {{0,
size.y}, {0.0, 1.0}},
665 ASSERT_TRUE(vertex_buffer);
670 auto buffer = context->CreateCommandBuffer();
674 buffer->SetLabel(
"Playground Command Buffer");
675 auto pass =
buffer->CreateBlitPass();
679 pass->SetLabel(
"Playground Blit Pass");
681 if (render_target.GetColorAttachments().empty()) {
686 pass->AddCopy(bridge, device_buffer);
687 pass->EncodeCommands(context->GetResourceAllocator());
689 if (!context->GetCommandQueue()->Submit({
buffer}).
ok()) {
695 auto buffer = context->CreateCommandBuffer();
699 buffer->SetLabel(
"Playground Command Buffer");
701 auto pass =
buffer->CreateRenderPass(render_target);
705 pass->SetLabel(
"Playground Render Pass");
707 pass->SetCommandLabel(
"Image");
708 pass->SetPipeline(mipmaps_pipeline);
709 pass->SetVertexBuffer(vertex_buffer);
711 VS::FrameInfo frame_info;
712 EXPECT_EQ(pass->GetOrthographicTransform(),
714 frame_info.mvp = pass->GetOrthographicTransform() *
716 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
718 FS::FragInfo frag_info;
720 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
722 const std::unique_ptr<const Sampler>& sampler =
723 context->GetSamplerLibrary()->GetSampler({});
726 context->GetResourceAllocator()->CreateTexture(texture_desc);
727 if (!
texture->SetContents(device_buffer->OnGetContents(),
732 FS::BindTex(*pass,
texture, sampler);
736 pass->EncodeCommands();
737 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
741 host_buffer->Reset();
749 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
752 ASSERT_TRUE(context);
754 using VS = MipmapsVertexShader;
755 using FS = MipmapsFragmentShader;
757 ASSERT_TRUE(
desc.has_value());
759 desc->SetStencilAttachmentDescriptors(std::nullopt);
760 auto mipmaps_pipeline =
761 context->GetPipelineLibrary()->GetPipeline(std::move(
desc)).Get();
762 ASSERT_TRUE(mipmaps_pipeline);
764 auto boston = CreateTextureForFixture(
"boston.jpg",
true);
772 {{0, 0}, {0.0, 0.0}},
773 {{
size.x, 0}, {1.0, 0.0}},
775 {{0, 0}, {0.0, 0.0}},
777 {{0,
size.y}, {0.0, 1.0}},
781 ASSERT_TRUE(vertex_buffer);
783 bool first_frame =
true;
786 const char* mip_filter_names[] = {
"Base",
"Nearest",
"Linear"};
789 const char* min_filter_names[] = {
"Nearest",
"Linear"};
794 static int selected_mip_filter = 1;
795 static int selected_min_filter = 0;
796 static float lod = 4.5;
798 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
799 ImGui::Combo(
"Mip filter", &selected_mip_filter, mip_filter_names,
800 sizeof(mip_filter_names) /
sizeof(
char*));
801 ImGui::Combo(
"Min filter", &selected_min_filter, min_filter_names,
802 sizeof(min_filter_names) /
sizeof(
char*));
803 ImGui::SliderFloat(
"LOD", &lod, 0, boston->GetMipCount() - 1);
806 auto buffer = context->CreateCommandBuffer();
810 buffer->SetLabel(
"Playground Command Buffer");
813 auto pass =
buffer->CreateBlitPass();
817 pass->SetLabel(
"Playground Blit Pass");
819 pass->GenerateMipmap(boston,
"Boston Mipmap");
821 pass->EncodeCommands(context->GetResourceAllocator());
827 auto pass =
buffer->CreateRenderPass(render_target);
831 pass->SetLabel(
"Playground Render Pass");
833 pass->SetCommandLabel(
"Image LOD");
834 pass->SetPipeline(mipmaps_pipeline);
835 pass->SetVertexBuffer(vertex_buffer);
837 VS::FrameInfo frame_info;
838 EXPECT_EQ(pass->GetOrthographicTransform(),
840 frame_info.mvp = pass->GetOrthographicTransform() *
842 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
844 FS::FragInfo frag_info;
846 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
849 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
850 sampler_desc.
min_filter = min_filters[selected_min_filter];
851 const std::unique_ptr<const Sampler>& sampler =
852 context->GetSamplerLibrary()->GetSampler(sampler_desc);
853 FS::BindTex(*pass, boston, sampler);
857 pass->EncodeCommands();
860 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
863 host_buffer->Reset();
870 using VS = ImpellerVertexShader;
871 using FS = ImpellerFragmentShader;
874 auto pipeline_descriptor =
876 ASSERT_TRUE(pipeline_descriptor.has_value());
878 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
880 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
881 ASSERT_TRUE(pipeline && pipeline->IsValid());
883 auto blue_noise = CreateTextureForFixture(
"blue_noise.png");
887 const std::unique_ptr<const Sampler>& noise_sampler =
888 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
890 auto cube_map = CreateTextureCubeForFixture(
891 {
"table_mountain_px.png",
"table_mountain_nx.png",
892 "table_mountain_py.png",
"table_mountain_ny.png",
893 "table_mountain_pz.png",
"table_mountain_nz.png"});
894 const std::unique_ptr<const Sampler>& cube_map_sampler =
895 context->GetSamplerLibrary()->GetSampler({});
899 auto size = pass.GetRenderTargetSize();
901 pass.SetPipeline(pipeline);
902 pass.SetCommandLabel(
"Impeller SDF scene");
910 pass.SetVertexBuffer(
builder.CreateVertexBuffer(*host_buffer));
912 VS::FrameInfo frame_info;
914 frame_info.mvp = pass.GetOrthographicTransform();
915 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
917 FS::FragInfo fs_uniform;
919 fs_uniform.time = GetSecondsElapsed();
920 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
921 FS::BindBlueNoise(pass, blue_noise, noise_sampler);
922 FS::BindCubeMap(pass, cube_map, cube_map_sampler);
925 host_buffer->Reset();
932 using VS = PlanetVertexShader;
933 using FS = PlanetFragmentShader;
936 auto pipeline_descriptor =
938 ASSERT_TRUE(pipeline_descriptor.has_value());
940 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
942 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
943 ASSERT_TRUE(pipeline && pipeline->IsValid());
948 static Scalar speed = 0.1;
949 static Scalar planet_size = 550.0;
950 static bool show_normals =
false;
951 static bool show_noise =
false;
952 static Scalar seed_value = 42.0;
954 auto size = pass.GetRenderTargetSize();
956 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
957 ImGui::SliderFloat(
"Speed", &speed, 0.0, 10.0);
958 ImGui::SliderFloat(
"Planet Size", &planet_size, 0.1, 1000);
959 ImGui::Checkbox(
"Show Normals", &show_normals);
960 ImGui::Checkbox(
"Show Noise", &show_noise);
961 ImGui::InputFloat(
"Seed Value", &seed_value);
964 pass.SetPipeline(pipeline);
965 pass.SetCommandLabel(
"Planet scene");
973 pass.SetVertexBuffer(
builder.CreateVertexBuffer(*host_buffer));
975 VS::FrameInfo frame_info;
977 frame_info.mvp = pass.GetOrthographicTransform();
978 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
980 FS::FragInfo fs_uniform;
982 fs_uniform.time = GetSecondsElapsed();
983 fs_uniform.speed = speed;
984 fs_uniform.planet_size = planet_size;
985 fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
986 fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
987 fs_uniform.seed_value = seed_value;
988 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
991 host_buffer->Reset();
998 using VS = ArrayVertexShader;
999 using FS = ArrayFragmentShader;
1002 auto pipeline_descriptor =
1004 ASSERT_TRUE(pipeline_descriptor.has_value());
1006 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1008 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1009 ASSERT_TRUE(pipeline && pipeline->IsValid());
1013 auto size = pass.GetRenderTargetSize();
1015 pass.SetPipeline(pipeline);
1016 pass.SetCommandLabel(
"Google Dots");
1024 pass.SetVertexBuffer(
builder.CreateVertexBuffer(*host_buffer));
1026 VS::FrameInfo frame_info;
1030 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1032 auto time = GetSecondsElapsed();
1033 auto y_pos = [&
time](
float x) {
1034 return 400 + 10 * std::cos(
time * 5 +
x / 6);
1037 FS::FragInfo fs_uniform = {
1038 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
1045 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1048 host_buffer->Reset();
1055 using VS = InactiveUniformsVertexShader;
1056 using FS = InactiveUniformsFragmentShader;
1059 auto pipeline_descriptor =
1061 ASSERT_TRUE(pipeline_descriptor.has_value());
1063 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1065 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1066 ASSERT_TRUE(pipeline && pipeline->IsValid());
1070 auto size = pass.GetRenderTargetSize();
1072 pass.SetPipeline(pipeline);
1073 pass.SetCommandLabel(
"Inactive Uniform");
1082 pass.SetVertexBuffer(
builder.CreateVertexBuffer(*host_buffer));
1084 VS::FrameInfo frame_info;
1088 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1090 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
1092 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1095 host_buffer->Reset();
1102 using VS = BoxFadeVertexShader;
1112 using VS = BoxFadeVertexShader;
1121 using VS = BoxFadeVertexShader;
1125 {{100, 100, 0.0}, {0.0, 0.0}},
1126 {{800, 100, 0.0}, {1.0, 0.0}},
1127 {{800, 800, 0.0}, {1.0, 1.0}},
1128 {{100, 800, 0.0}, {0.0, 1.0}},
1144 labels_.push_back(
"Never");
1146 labels_.push_back(
"Always");
1148 labels_.push_back(
"Less");
1150 labels_.push_back(
"Equal");
1152 labels_.push_back(
"LessEqual");
1154 labels_.push_back(
"Greater");
1156 labels_.push_back(
"NotEqual");
1158 labels_.push_back(
"GreaterEqual");
1160 assert(labels_.size() == functions_.size());
1163 const char*
const*
labels()
const {
return &labels_[0]; }
1165 int size()
const {
return labels_.size(); }
1168 for (
size_t i = 0;
i < functions_.size();
i++) {
1169 if (functions_[
i] == func) {
1180 std::vector<const char*> labels_;
1181 std::vector<CompareFunction> functions_;
1190 using VS = BoxFadeVertexShader;
1191 using FS = BoxFadeFragmentShader;
1193 ASSERT_TRUE(context);
1195 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1196 ASSERT_TRUE(
desc.has_value());
1202 {{100, 100, 0.0}, {0.0, 0.0}},
1203 {{800, 100, 0.0}, {1.0, 0.0}},
1204 {{800, 800, 0.0}, {1.0, 1.0}},
1205 {{100, 100, 0.0}, {0.0, 0.0}},
1206 {{800, 800, 0.0}, {1.0, 1.0}},
1207 {{100, 800, 0.0}, {0.0, 1.0}},
1209 auto vertex_buffer =
1211 ASSERT_TRUE(vertex_buffer);
1214 desc->SetStencilAttachmentDescriptors(std::nullopt);
1216 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1217 auto boston = CreateTextureForFixture(
"boston.jpg");
1218 ASSERT_TRUE(bridge && boston);
1219 const std::unique_ptr<const Sampler>& sampler =
1220 context->GetSamplerLibrary()->GetSampler({});
1221 ASSERT_TRUE(sampler);
1223 static bool mirror =
false;
1224 static int stencil_reference_write = 0xFF;
1225 static int stencil_reference_read = 0x1;
1226 std::vector<uint8_t> stencil_contents;
1227 static int last_stencil_contents_reference_value = 0;
1228 static int current_front_compare =
1230 static int current_back_compare =
1235 auto buffer = context->CreateCommandBuffer();
1239 buffer->SetLabel(
"Playground Command Buffer");
1247 render_target.SetupDepthStencilAttachments(
1248 *context, *context->GetResourceAllocator(),
1249 render_target.GetRenderTargetSize(),
true,
"stencil", stencil_config);
1251 const auto target_width = render_target.GetRenderTargetSize().width;
1252 const auto target_height = render_target.GetRenderTargetSize().height;
1253 const size_t target_size = target_width * target_height;
1254 if (stencil_contents.size() != target_size ||
1255 last_stencil_contents_reference_value != stencil_reference_write) {
1256 stencil_contents.resize(target_size);
1257 last_stencil_contents_reference_value = stencil_reference_write;
1258 for (
int y = 0;
y < target_height;
y++) {
1259 for (
int x = 0;
x < target_width;
x++) {
1260 const auto index =
y * target_width +
x;
1261 const auto kCheckSize = 64;
1263 (((
y / kCheckSize) + (
x / kCheckSize)) % 2 == 0) *
1264 stencil_reference_write;
1265 stencil_contents[index] =
value;
1269 if (!render_target.GetStencilAttachment()->texture->SetContents(
1270 stencil_contents.data(), stencil_contents.size(), 0,
false)) {
1271 VALIDATION_LOG <<
"Could not upload stencil contents to device memory";
1274 auto pass =
buffer->CreateRenderPass(render_target);
1278 pass->SetLabel(
"Stencil Buffer");
1279 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1280 ImGui::SliderInt(
"Stencil Write Value", &stencil_reference_write, 0,
1282 ImGui::SliderInt(
"Stencil Compare Value", &stencil_reference_read, 0,
1284 ImGui::Checkbox(
"Back face mode", &
mirror);
1285 ImGui::ListBox(
"Front face compare function", ¤t_front_compare,
1287 ImGui::ListBox(
"Back face compare function", ¤t_back_compare,
1297 desc->SetStencilAttachmentDescriptors(front, back);
1298 auto pipeline = context->GetPipelineLibrary()->GetPipeline(
desc).Get();
1300 assert(pipeline && pipeline->IsValid());
1302 pass->SetCommandLabel(
"Box");
1303 pass->SetPipeline(pipeline);
1304 pass->SetStencilReference(stencil_reference_read);
1305 pass->SetVertexBuffer(vertex_buffer);
1307 VS::UniformBuffer uniforms;
1308 EXPECT_EQ(pass->GetOrthographicTransform(),
1310 uniforms.mvp = pass->GetOrthographicTransform() *
1315 VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1317 FS::FrameInfo frame_info;
1318 frame_info.current_time = GetSecondsElapsed();
1319 frame_info.cursor_position = GetCursorPosition();
1320 frame_info.window_size.x = GetWindowSize().width;
1321 frame_info.window_size.y = GetWindowSize().height;
1323 FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1324 FS::BindContents1(*pass, boston, sampler);
1325 FS::BindContents2(*pass, bridge, sampler);
1326 if (!pass->Draw().ok()) {
1329 pass->EncodeCommands();
1332 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1335 host_buffer->Reset();
1343 auto cmd_buffer = context->CreateCommandBuffer();
1344 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1347 auto render_target = render_target_cache->CreateOffscreen(
1348 *context, {100, 100}, 1);
1349 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1351 EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1352 EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1353 render_target.GetRenderTargetPixelFormat());
1354 EXPECT_EQ(render_pass->HasStencilAttachment(),
1355 render_target.GetStencilAttachment().has_value());
1356 EXPECT_EQ(render_pass->GetRenderTargetSize(),
1357 render_target.GetRenderTargetSize());
1358 render_pass->EncodeCommands();
1362 RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat) {
1364 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1367 RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1368 *context, {100, 100}, 1);
1370 ->texture->GetTextureDescriptor()
1372 GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1375template <
class VertexShader,
class FragmentShader>
1377 const std::shared_ptr<Context>& context) {
1379 auto pipeline_desc =
1380 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1381 if (!pipeline_desc.has_value()) {
1385 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1387 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1388 if (!pipeline || !pipeline->IsValid()) {
1399 GTEST_SKIP_(
"Not supported on GLES.");
1403 using TextureVS = TextureVertexShader;
1404 using TextureFS = TextureFragmentShader;
1406 using SepiaVS = SepiaVertexShader;
1407 using SepiaFS = SepiaFragmentShader;
1410 ASSERT_TRUE(context);
1412 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1414 "This test uses framebuffer fetch and the backend doesn't support it.");
1419 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1420 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1422 ASSERT_TRUE(texture_pipeline);
1423 ASSERT_TRUE(sepia_pipeline);
1428 {{100, 100, 0.0}, {0.0, 0.0}},
1429 {{800, 100, 0.0}, {1.0, 0.0}},
1430 {{800, 800, 0.0}, {1.0, 1.0}},
1431 {{100, 100, 0.0}, {0.0, 0.0}},
1432 {{800, 800, 0.0}, {1.0, 1.0}},
1433 {{100, 800, 0.0}, {0.0, 1.0}},
1446 auto boston = CreateTextureForFixture(
"boston.jpg");
1447 ASSERT_TRUE(boston);
1449 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1450 ASSERT_TRUE(sampler);
1457 pass.SetPipeline(texture_pipeline);
1459 *context->GetResourceAllocator()));
1460 TextureVS::UniformBuffer uniforms;
1463 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1464 TextureFS::BindTextureContents(pass, boston, sampler);
1465 if (!pass.Draw().ok()) {
1472 pass.SetPipeline(sepia_pipeline);
1474 *context->GetResourceAllocator()));
1475 SepiaVS::UniformBuffer uniforms;
1478 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1479 if (!pass.Draw().ok()) {
1494 GTEST_SKIP_(
"Not supported on GLES.");
1498 using TextureVS = TextureVertexShader;
1499 using TextureFS = TextureFragmentShader;
1501 using SwizzleVS = SepiaVertexShader;
1502 using SwizzleFS = SwizzleFragmentShader;
1504 using SepiaVS = SepiaVertexShader;
1505 using SepiaFS = SepiaFragmentShader;
1508 ASSERT_TRUE(context);
1510 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1512 "This test uses framebuffer fetch and the backend doesn't support it.");
1517 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1518 auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1519 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1521 ASSERT_TRUE(texture_pipeline);
1522 ASSERT_TRUE(swizzle_pipeline);
1523 ASSERT_TRUE(sepia_pipeline);
1528 {{100, 100, 0.0}, {0.0, 0.0}},
1529 {{800, 100, 0.0}, {1.0, 0.0}},
1530 {{800, 800, 0.0}, {1.0, 1.0}},
1531 {{100, 100, 0.0}, {0.0, 0.0}},
1532 {{800, 800, 0.0}, {1.0, 1.0}},
1533 {{100, 800, 0.0}, {0.0, 1.0}},
1546 auto boston = CreateTextureForFixture(
"boston.jpg");
1547 ASSERT_TRUE(boston);
1549 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1550 ASSERT_TRUE(sampler);
1557 pass.SetPipeline(texture_pipeline);
1559 *context->GetResourceAllocator()));
1560 TextureVS::UniformBuffer uniforms;
1563 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1564 TextureFS::BindTextureContents(pass, boston, sampler);
1565 if (!pass.Draw().ok()) {
1572 pass.SetPipeline(sepia_pipeline);
1574 *context->GetResourceAllocator()));
1575 SepiaVS::UniformBuffer uniforms;
1578 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1579 if (!pass.Draw().ok()) {
1586 pass.SetPipeline(swizzle_pipeline);
1588 *context->GetResourceAllocator()));
1589 SwizzleVS::UniformBuffer uniforms;
1592 SwizzleVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1593 if (!pass.Draw().ok()) {
static unsigned mirror(SkFixed fx, int max)
static bool ok(int result)
constexpr double ToSecondsF() const
TimeDelta ToEpochDelta() const
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)
Render passes encode render commands directed as one specific render target into an underlying comman...
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor > > &pipeline)
The pipeline to use for this command.
const Matrix & GetOrthographicTransform() const
ISize GetRenderTargetSize() const
virtual void SetInstanceCount(size_t count)
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
const std::optional< DepthAttachment > & GetDepthAttachment() const
std::function< bool(RenderTarget &render_target)> RenderCallback
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
size_t GetVertexCount() const
size_t GetIndexCount() const
VertexBufferBuilder & AppendIndex(IndexType_ index)
void SetLabel(const std::string &label)
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
constexpr impeller::IndexType GetIndexType() const
CompareFunction FunctionOf(int index) const
const char *const * labels() const
int IndexOf(CompareFunction func) const
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_UNREACHABLE()
SK_API GrDirectContext * GetContext(const SkImage *src)
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 which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer 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
PlaygroundTest RendererTest
std::shared_ptr< Pipeline< PipelineDescriptor > > CreateDefaultPipeline(const std::shared_ptr< Context > &context)
static const CompareFunctionUIData & CompareFunctionUI()
INSTANTIATE_PLAYGROUND_SUITE(AiksTest)
TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
@ kNone
Does not use the index buffer.
MipFilter
Options for selecting and filtering between mipmap levels.
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
@ kNearest
The nearst mipmap level is selected.
@ kEqual
Comparison test passes if new_value == current_value.
@ kLessEqual
Comparison test passes if new_value <= current_value.
@ kGreaterEqual
Comparison test passes if new_value >= current_value.
@ kAlways
Comparison test passes always passes.
@ kLess
Comparison test passes if new_value < current_value.
@ kGreater
Comparison test passes if new_value > current_value.
@ kNotEqual
Comparison test passes if new_value != current_value.
@ kNever
Comparison test never passes.
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
@ kNearest
Select nearest to the sample point. Most widely supported.
static double time(int loops, Benchmark *bench, Target *target)
std::shared_ptr< Texture > texture
std::shared_ptr< const DeviceBuffer > buffer
static constexpr Color Red()
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
static constexpr Color Yellow()
static constexpr Color Blue()
static constexpr Color Green()
static constexpr Matrix MakeOrthographic(TSize< T > size)
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
static Matrix MakeRotationY(Radians r)
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
static Matrix MakeRotationX(Radians r)
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
static std::optional< PipelineDescriptor > MakeDefaultPipelineDescriptor(const Context &context, const std::vector< Scalar > &constants={})
Create a default pipeline descriptor using the combination reflected shader information....
SamplerAddressMode width_address_mode
SamplerAddressMode height_address_mode
CompareFunction stencil_compare
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
std::shared_ptr< const fml::Mapping > data