12#include "impeller/fixtures/array.frag.h"
13#include "impeller/fixtures/array.vert.h"
14#include "impeller/fixtures/box_fade.frag.h"
15#include "impeller/fixtures/box_fade.vert.h"
16#include "impeller/fixtures/colors.frag.h"
17#include "impeller/fixtures/colors.vert.h"
18#include "impeller/fixtures/impeller.frag.h"
19#include "impeller/fixtures/impeller.vert.h"
20#include "impeller/fixtures/inactive_uniforms.frag.h"
21#include "impeller/fixtures/inactive_uniforms.vert.h"
22#include "impeller/fixtures/instanced_draw.frag.h"
23#include "impeller/fixtures/instanced_draw.vert.h"
24#include "impeller/fixtures/mipmaps.frag.h"
25#include "impeller/fixtures/mipmaps.vert.h"
26#include "impeller/fixtures/planet.frag.h"
27#include "impeller/fixtures/planet.vert.h"
28#include "impeller/fixtures/sepia.frag.h"
29#include "impeller/fixtures/sepia.vert.h"
30#include "impeller/fixtures/swizzle.frag.h"
31#include "impeller/fixtures/texture.frag.h"
32#include "impeller/fixtures/texture.vert.h"
41#include "third_party/imgui/imgui.h"
47std::pair<std::shared_ptr<impeller::HostBuffer>,
48 std::shared_ptr<impeller::HostBuffer>>
49createHostBuffers(
const std::shared_ptr<impeller::Context>&
context) {
52 context->GetCapabilities()->GetMinimumUniformAlignment());
53 auto indexes_host_buffer =
54 context->GetCapabilities()->NeedsPartitionedHostBuffer()
57 context->GetCapabilities()->GetMinimumUniformAlignment())
59 return {data_host_buffer, indexes_host_buffer};
70 using VS = BoxFadeVertexShader;
71 using FS = BoxFadeFragmentShader;
75 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*
context);
76 ASSERT_TRUE(desc.has_value());
78 desc->SetStencilAttachmentDescriptors(std::nullopt);
84 {{100, 100, 0.0}, {0.0, 0.0}},
85 {{800, 100, 0.0}, {1.0, 0.0}},
86 {{800, 800, 0.0}, {1.0, 1.0}},
87 {{100, 100, 0.0}, {0.0, 0.0}},
88 {{800, 800, 0.0}, {1.0, 1.0}},
89 {{100, 800, 0.0}, {0.0, 1.0}},
91 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
92 auto boston = CreateTextureForFixture(
"boston.jpg");
93 ASSERT_TRUE(bridge && boston);
97 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
99 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
100 static bool wireframe;
101 ImGui::Checkbox(
"Wireframe", &wireframe);
105 auto pipeline =
context->GetPipelineLibrary()->GetPipeline(desc).Get();
109 pass.SetCommandLabel(
"Box");
111 pass.SetVertexBuffer(
114 VS::UniformBuffer uniforms;
115 EXPECT_EQ(pass.GetOrthographicTransform(),
119 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
121 FS::FrameInfo frame_info;
122 frame_info.current_time = GetSecondsElapsed();
123 frame_info.cursor_position = GetCursorPosition();
124 frame_info.window_size.x = GetWindowSize().width;
125 frame_info.window_size.y = GetWindowSize().height;
127 FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
128 FS::BindContents1(pass, boston, sampler);
129 FS::BindContents2(pass, bridge, sampler);
131 data_host_buffer->Reset();
132 return pass.Draw().ok();
138 using VS = ColorsVertexShader;
139 using FS = ColorsFragmentShader;
143 ASSERT_TRUE(desc.has_value());
147 desc->ClearStencilAttachments();
151 auto vertex_desc = std::make_shared<VertexDescriptor>();
158 const std::vector<ShaderStageIOSlot> io_slots = {position_slot, color_slot};
159 const std::vector<ShaderStageBufferLayout> layouts = {
162 vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
163 vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
164 vertex_desc->SetStageInputs(io_slots, layouts);
165 desc->SetVertexDescriptor(std::move(vertex_desc));
167 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
184 Color::Red(), Color::Yellow(), Color::Green(), Color::Blue(),
185 Color::Green(), Color::Blue(), Color::Red(), Color::Yellow(),
187 uint16_t indices[36] = {
197 auto device_buffer =
context->GetResourceAllocator()->CreateBufferWithCopy(
198 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
201 ASSERT_TRUE(sampler);
204 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
207 static Scalar distance = 10;
209 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
210 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
211 ImGui::SliderFloat(
"Camera distance", &distance, 0, 30);
214 pass.SetCommandLabel(
"Perspective Cube");
217 std::array<BufferView, 2> vertex_buffers = {
219 Range(offsetof(Cube, positions),
sizeof(Cube::positions))),
221 Range(offsetof(Cube, colors),
sizeof(Cube::colors))),
225 device_buffer,
Range(offsetof(Cube, indices),
sizeof(Cube::indices)));
226 pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
227 pass.SetElementCount(36);
230 VS::UniformBuffer uniforms;
231 Scalar time = GetSecondsElapsed();
232 euler_angles =
Vector3(0.19 * time, 0.7 * time, 0.43 * time);
240 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
242 data_host_buffer->Reset();
243 return pass.Draw().ok();
249 using VS = BoxFadeVertexShader;
250 using FS = BoxFadeFragmentShader;
254 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*
context);
255 ASSERT_TRUE(desc.has_value());
257 desc->SetStencilAttachmentDescriptors(std::nullopt);
259 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
260 ASSERT_TRUE(box_pipeline);
266 {{100, 100, 0.0}, {0.0, 0.0}},
267 {{800, 100, 0.0}, {1.0, 0.0}},
268 {{800, 800, 0.0}, {1.0, 1.0}},
269 {{100, 100, 0.0}, {0.0, 0.0}},
270 {{800, 800, 0.0}, {1.0, 1.0}},
271 {{100, 800, 0.0}, {0.0, 1.0}},
275 ASSERT_TRUE(vertex_buffer);
277 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
278 auto boston = CreateTextureForFixture(
"boston.jpg");
279 ASSERT_TRUE(bridge && boston);
281 ASSERT_TRUE(sampler);
283 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
285 for (
size_t i = 0;
i < 1;
i++) {
286 for (
size_t j = 0; j < 1; j++) {
287 pass.SetCommandLabel(
"Box");
288 pass.SetPipeline(box_pipeline);
289 pass.SetVertexBuffer(vertex_buffer);
291 FS::FrameInfo frame_info;
292 frame_info.current_time = GetSecondsElapsed();
293 frame_info.cursor_position = GetCursorPosition();
294 frame_info.window_size.x = GetWindowSize().width;
295 frame_info.window_size.y = GetWindowSize().height;
297 FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
298 FS::BindContents1(pass, boston, sampler);
299 FS::BindContents2(pass, bridge, sampler);
301 VS::UniformBuffer uniforms;
302 EXPECT_EQ(pass.GetOrthographicTransform(),
304 uniforms.mvp = pass.GetOrthographicTransform() *
307 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
308 if (!pass.Draw().ok()) {
314 data_host_buffer->Reset();
321 using VS = BoxFadeVertexShader;
322 using FS = BoxFadeFragmentShader;
327 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*
context);
329 pipeline_desc->ClearDepthAttachment();
332 ASSERT_TRUE(pipeline_desc.has_value());
334 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
335 ASSERT_TRUE(box_pipeline);
336 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
341 {{100, 100, 0.0}, {0.0, 0.0}},
342 {{800, 100, 0.0}, {1.0, 0.0}},
343 {{800, 800, 0.0}, {1.0, 1.0}},
344 {{100, 100, 0.0}, {0.0, 0.0}},
345 {{800, 800, 0.0}, {1.0, 1.0}},
346 {{100, 800, 0.0}, {0.0, 1.0}},
350 ASSERT_TRUE(vertex_buffer);
352 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
353 auto boston = CreateTextureForFixture(
"boston.jpg");
354 ASSERT_TRUE(bridge && boston);
356 ASSERT_TRUE(sampler);
358 std::shared_ptr<RenderPass> r2t_pass;
359 auto cmd_buffer =
context->CreateCommandBuffer();
360 ASSERT_TRUE(cmd_buffer);
367 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
368 texture_descriptor.
format =
369 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
371 texture_descriptor.
size = {400, 400};
376 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
380 color0.
texture->SetLabel(
"r2t_target");
387 stencil_texture_desc.
size = texture_descriptor.
size;
391 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
396 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
397 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
400 r2t_pass->SetCommandLabel(
"Box");
401 r2t_pass->SetPipeline(box_pipeline);
402 r2t_pass->SetVertexBuffer(vertex_buffer);
404 FS::FrameInfo frame_info;
405 frame_info.current_time = GetSecondsElapsed();
406 frame_info.cursor_position = GetCursorPosition();
407 frame_info.window_size.x = GetWindowSize().width;
408 frame_info.window_size.y = GetWindowSize().height;
410 FS::BindFrameInfo(*r2t_pass, data_host_buffer->EmplaceUniform(frame_info));
411 FS::BindContents1(*r2t_pass, boston, sampler);
412 FS::BindContents2(*r2t_pass, bridge, sampler);
414 VS::UniformBuffer uniforms;
417 VS::BindUniformBuffer(*r2t_pass, data_host_buffer->EmplaceUniform(uniforms));
418 ASSERT_TRUE(r2t_pass->Draw().ok());
419 ASSERT_TRUE(r2t_pass->EncodeCommands());
429 GTEST_SKIP() <<
"This test's instance-ID mechanism requires OpenGL ES 3.1; "
430 "CanRenderInstancedWithVertexAttributes covers the "
431 "portable instance-rate path.";
433 using VS = InstancedDrawVertexShader;
434 using FS = InstancedDrawFragmentShader;
438 VS::PerVertexData{
Point{10, 10}},
439 VS::PerVertexData{
Point{10, 110}},
440 VS::PerVertexData{
Point{110, 10}},
441 VS::PerVertexData{
Point{10, 110}},
442 VS::PerVertexData{
Point{110, 10}},
443 VS::PerVertexData{
Point{110, 110}},
446 ASSERT_NE(GetContext(),
nullptr);
449 ->GetPipelineLibrary()
453 .SetStencilAttachmentDescriptors(std::nullopt))
458 static constexpr size_t kInstancesCount = 5u;
459 VS::InstanceInfo<kInstancesCount> instances;
460 for (
size_t i = 0;
i < kInstancesCount;
i++) {
464 auto [data_host_buffer, indexes_host_buffer] =
465 createHostBuffers(GetContext());
466 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
470 VS::FrameInfo frame_info;
475 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
476 VS::BindInstanceInfo(pass,
477 data_host_buffer->EmplaceStorageBuffer(instances));
484 data_host_buffer->Reset();
492 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
497 using VS = MipmapsVertexShader;
498 using FS = MipmapsFragmentShader;
500 ASSERT_TRUE(desc.has_value());
502 desc->SetStencilAttachmentDescriptors(std::nullopt);
503 auto mipmaps_pipeline =
504 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
505 ASSERT_TRUE(mipmaps_pipeline);
510 texture_desc.
size = {800, 600};
513 auto texture =
context->GetResourceAllocator()->CreateTexture(texture_desc);
516 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
517 auto boston = CreateTextureForFixture(
"boston.jpg");
518 ASSERT_TRUE(bridge && boston);
520 ASSERT_TRUE(sampler);
527 {{0, 0}, {0.0, 0.0}},
528 {{
size.x, 0}, {1.0, 0.0}},
530 {{0, 0}, {0.0, 0.0}},
532 {{0,
size.y}, {0.0, 1.0}},
536 ASSERT_TRUE(vertex_buffer);
538 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
544 buffer->SetLabel(
"Playground Command Buffer");
547 auto pass =
buffer->CreateBlitPass();
551 pass->SetLabel(
"Playground Blit Pass");
554 pass->AddCopy(bridge,
texture);
556 if (!pass->EncodeCommands()) {
562 auto pass =
buffer->CreateRenderPass(render_target);
566 pass->SetLabel(
"Playground Render Pass");
568 pass->SetCommandLabel(
"Image");
569 pass->SetPipeline(mipmaps_pipeline);
570 pass->SetVertexBuffer(vertex_buffer);
572 VS::FrameInfo frame_info;
573 EXPECT_EQ(pass->GetOrthographicTransform(),
575 frame_info.mvp = pass->GetOrthographicTransform() *
577 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
579 FS::FragInfo frag_info;
581 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
583 auto sampler =
context->GetSamplerLibrary()->GetSampler({});
584 FS::BindTex(*pass,
texture, sampler);
588 pass->EncodeCommands();
591 if (!
context->GetCommandQueue()->Submit({buffer}).ok()) {
594 data_host_buffer->Reset();
603 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
608 using VS = MipmapsVertexShader;
609 using FS = MipmapsFragmentShader;
611 ASSERT_TRUE(desc.has_value());
613 desc->SetStencilAttachmentDescriptors(std::nullopt);
614 auto mipmaps_pipeline =
615 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
616 ASSERT_TRUE(mipmaps_pipeline);
618 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
619 auto boston = CreateTextureForFixture(
"boston.jpg");
620 ASSERT_TRUE(bridge && boston);
622 ASSERT_TRUE(sampler);
627 texture_desc.
size = bridge->GetTextureDescriptor().size;
633 device_buffer_desc.
size =
634 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
636 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
643 {{0, 0}, {0.0, 0.0}},
644 {{
size.x, 0}, {1.0, 0.0}},
646 {{0, 0}, {0.0, 0.0}},
648 {{0,
size.y}, {0.0, 1.0}},
652 ASSERT_TRUE(vertex_buffer);
654 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
661 buffer->SetLabel(
"Playground Command Buffer");
662 auto pass =
buffer->CreateBlitPass();
666 pass->SetLabel(
"Playground Blit Pass");
669 pass->AddCopy(bridge, device_buffer);
670 pass->EncodeCommands();
682 buffer->SetLabel(
"Playground Command Buffer");
684 auto pass =
buffer->CreateRenderPass(render_target);
688 pass->SetLabel(
"Playground Render Pass");
690 pass->SetCommandLabel(
"Image");
691 pass->SetPipeline(mipmaps_pipeline);
692 pass->SetVertexBuffer(vertex_buffer);
694 VS::FrameInfo frame_info;
695 EXPECT_EQ(pass->GetOrthographicTransform(),
697 frame_info.mvp = pass->GetOrthographicTransform() *
699 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
701 FS::FragInfo frag_info;
703 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
706 context->GetSamplerLibrary()->GetSampler({});
709 context->GetResourceAllocator()->CreateTexture(texture_desc);
710 if (!
texture->SetContents(device_buffer->OnGetContents(),
711 buffer_view.GetRange().length)) {
715 FS::BindTex(*pass,
texture, sampler);
719 pass->EncodeCommands();
720 if (!
context->GetCommandQueue()->Submit({buffer}).ok()) {
724 data_host_buffer->Reset();
733 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
738 using VS = MipmapsVertexShader;
739 using FS = MipmapsFragmentShader;
741 ASSERT_TRUE(desc.has_value());
743 desc->SetStencilAttachmentDescriptors(std::nullopt);
744 auto mipmaps_pipeline =
745 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
746 ASSERT_TRUE(mipmaps_pipeline);
748 auto boston = CreateTextureForFixture(
"boston.jpg",
true);
756 {{0, 0}, {0.0, 0.0}},
757 {{
size.x, 0}, {1.0, 0.0}},
759 {{0, 0}, {0.0, 0.0}},
761 {{0,
size.y}, {0.0, 1.0}},
765 ASSERT_TRUE(vertex_buffer);
767 bool first_frame =
true;
768 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
770 const char* mip_filter_names[] = {
"Base",
"Nearest",
"Linear"};
773 const char* min_filter_names[] = {
"Nearest",
"Linear"};
778 static int selected_mip_filter = 1;
779 static int selected_min_filter = 0;
780 static float lod = 4.5;
782 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
783 ImGui::Combo(
"Mip filter", &selected_mip_filter, mip_filter_names,
784 sizeof(mip_filter_names) /
sizeof(
char*));
785 ImGui::Combo(
"Min filter", &selected_min_filter, min_filter_names,
786 sizeof(min_filter_names) /
sizeof(
char*));
787 ImGui::SliderFloat(
"LOD", &lod, 0, boston->GetMipCount() - 1);
794 buffer->SetLabel(
"Playground Command Buffer");
797 auto pass =
buffer->CreateBlitPass();
801 pass->SetLabel(
"Playground Blit Pass");
803 pass->GenerateMipmap(boston,
"Boston Mipmap");
805 pass->EncodeCommands();
811 auto pass =
buffer->CreateRenderPass(render_target);
815 pass->SetLabel(
"Playground Render Pass");
817 pass->SetCommandLabel(
"Image LOD");
818 pass->SetPipeline(mipmaps_pipeline);
819 pass->SetVertexBuffer(vertex_buffer);
821 VS::FrameInfo frame_info;
822 EXPECT_EQ(pass->GetOrthographicTransform(),
824 frame_info.mvp = pass->GetOrthographicTransform() *
826 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
828 FS::FragInfo frag_info;
830 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
833 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
834 sampler_desc.
min_filter = min_filters[selected_min_filter];
836 context->GetSamplerLibrary()->GetSampler(sampler_desc);
837 FS::BindTex(*pass, boston, sampler);
841 pass->EncodeCommands();
844 if (!
context->GetCommandQueue()->Submit({buffer}).ok()) {
847 data_host_buffer->Reset();
854 using VS = ImpellerVertexShader;
855 using FS = ImpellerFragmentShader;
858 auto pipeline_descriptor =
860 ASSERT_TRUE(pipeline_descriptor.has_value());
862 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
864 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
867 auto blue_noise = CreateTextureForFixture(
"blue_noise.png");
872 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
874 auto cube_map = CreateTextureCubeForFixture(
875 {
"table_mountain_px.png",
"table_mountain_nx.png",
876 "table_mountain_py.png",
"table_mountain_ny.png",
877 "table_mountain_pz.png",
"table_mountain_nz.png"});
879 context->GetSamplerLibrary()->GetSampler({});
881 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
883 auto size = pass.GetRenderTargetSize();
886 pass.SetCommandLabel(
"Impeller SDF scene");
894 pass.SetVertexBuffer(
897 VS::FrameInfo frame_info;
899 frame_info.mvp = pass.GetOrthographicTransform();
900 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
902 FS::FragInfo fs_uniform;
904 fs_uniform.time = GetSecondsElapsed();
905 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
906 FS::BindBlueNoise(pass, blue_noise, noise_sampler);
907 FS::BindCubeMap(pass, cube_map, cube_map_sampler);
910 data_host_buffer->Reset();
917 using VS = PlanetVertexShader;
918 using FS = PlanetFragmentShader;
921 auto pipeline_descriptor =
923 ASSERT_TRUE(pipeline_descriptor.has_value());
925 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
927 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
930 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
932 static Scalar speed = 0.1;
933 static Scalar planet_size = 550.0;
934 static bool show_normals =
false;
935 static bool show_noise =
false;
936 static Scalar seed_value = 42.0;
938 auto size = pass.GetRenderTargetSize();
940 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
941 ImGui::SliderFloat(
"Speed", &speed, 0.0, 10.0);
942 ImGui::SliderFloat(
"Planet Size", &planet_size, 0.1, 1000);
943 ImGui::Checkbox(
"Show Normals", &show_normals);
944 ImGui::Checkbox(
"Show Noise", &show_noise);
945 ImGui::InputFloat(
"Seed Value", &seed_value);
949 pass.SetCommandLabel(
"Planet scene");
957 pass.SetVertexBuffer(
960 VS::FrameInfo frame_info;
962 frame_info.mvp = pass.GetOrthographicTransform();
963 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
965 FS::FragInfo fs_uniform;
967 fs_uniform.time = GetSecondsElapsed();
968 fs_uniform.speed = speed;
969 fs_uniform.planet_size = planet_size;
970 fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
971 fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
972 fs_uniform.seed_value = seed_value;
973 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
976 data_host_buffer->Reset();
983 using VS = ArrayVertexShader;
984 using FS = ArrayFragmentShader;
987 auto pipeline_descriptor =
989 ASSERT_TRUE(pipeline_descriptor.has_value());
991 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
993 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
996 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
998 auto size = pass.GetRenderTargetSize();
1001 pass.SetCommandLabel(
"Google Dots");
1009 pass.SetVertexBuffer(
1012 VS::FrameInfo frame_info;
1016 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1018 auto time = GetSecondsElapsed();
1019 auto y_pos = [&time](
float x) {
1020 return 400 + 10 * std::cos(time * 5 +
x / 6);
1023 FS::FragInfo fs_uniform = {
1024 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
1031 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1034 data_host_buffer->Reset();
1041 using VS = InactiveUniformsVertexShader;
1042 using FS = InactiveUniformsFragmentShader;
1045 auto pipeline_descriptor =
1047 ASSERT_TRUE(pipeline_descriptor.has_value());
1049 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1051 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1054 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
1056 auto size = pass.GetRenderTargetSize();
1059 pass.SetCommandLabel(
"Inactive Uniform");
1068 pass.SetVertexBuffer(
1071 VS::FrameInfo frame_info;
1075 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1077 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
1079 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1082 data_host_buffer->Reset();
1089 using VS = BoxFadeVertexShader;
1099 using VS = BoxFadeVertexShader;
1108 using VS = BoxFadeVertexShader;
1112 {{100, 100, 0.0}, {0.0, 0.0}},
1113 {{800, 100, 0.0}, {1.0, 0.0}},
1114 {{800, 800, 0.0}, {1.0, 1.0}},
1115 {{100, 800, 0.0}, {0.0, 1.0}},
1131 labels_.push_back(
"Never");
1133 labels_.push_back(
"Always");
1135 labels_.push_back(
"Less");
1137 labels_.push_back(
"Equal");
1139 labels_.push_back(
"LessEqual");
1141 labels_.push_back(
"Greater");
1143 labels_.push_back(
"NotEqual");
1145 labels_.push_back(
"GreaterEqual");
1147 assert(labels_.size() == functions_.size());
1150 const char*
const*
labels()
const {
return &labels_[0]; }
1152 int size()
const {
return labels_.size(); }
1155 for (
size_t i = 0;
i < functions_.size();
i++) {
1156 if (functions_[
i] == func) {
1167 std::vector<const char*> labels_;
1168 std::vector<CompareFunction> functions_;
1177 using VS = BoxFadeVertexShader;
1178 using FS = BoxFadeFragmentShader;
1182 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*
context);
1183 ASSERT_TRUE(desc.has_value());
1189 {{100, 100, 0.0}, {0.0, 0.0}},
1190 {{800, 100, 0.0}, {1.0, 0.0}},
1191 {{800, 800, 0.0}, {1.0, 1.0}},
1192 {{100, 100, 0.0}, {0.0, 0.0}},
1193 {{800, 800, 0.0}, {1.0, 1.0}},
1194 {{100, 800, 0.0}, {0.0, 1.0}},
1196 auto vertex_buffer =
1198 ASSERT_TRUE(vertex_buffer);
1201 desc->SetStencilAttachmentDescriptors(std::nullopt);
1203 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1204 auto boston = CreateTextureForFixture(
"boston.jpg");
1205 ASSERT_TRUE(bridge && boston);
1207 ASSERT_TRUE(sampler);
1209 static bool mirror =
false;
1210 static int stencil_reference_write = 0xFF;
1211 static int stencil_reference_read = 0x1;
1212 std::vector<uint8_t> stencil_contents;
1213 static int last_stencil_contents_reference_value = 0;
1214 static int current_front_compare =
1216 static int current_back_compare =
1219 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(
context);
1225 buffer->SetLabel(
"Playground Command Buffer");
1233 render_target.SetupDepthStencilAttachments(
1235 render_target.GetRenderTargetSize(),
true,
"stencil", stencil_config);
1237 const auto target_width = render_target.GetRenderTargetSize().width;
1238 const auto target_height = render_target.GetRenderTargetSize().height;
1239 const size_t target_size = target_width * target_height;
1240 if (stencil_contents.size() != target_size ||
1241 last_stencil_contents_reference_value != stencil_reference_write) {
1242 stencil_contents.resize(target_size);
1243 last_stencil_contents_reference_value = stencil_reference_write;
1244 for (
int y = 0;
y < target_height;
y++) {
1245 for (
int x = 0;
x < target_width;
x++) {
1246 const auto index =
y * target_width +
x;
1247 const auto kCheckSize = 64;
1249 (((
y / kCheckSize) + (
x / kCheckSize)) % 2 == 0) *
1250 stencil_reference_write;
1251 stencil_contents[index] =
value;
1255 if (!render_target.GetStencilAttachment()->texture->SetContents(
1256 stencil_contents.data(), stencil_contents.size(), 0,
false)) {
1257 VALIDATION_LOG <<
"Could not upload stencil contents to device memory";
1260 auto pass =
buffer->CreateRenderPass(render_target);
1264 pass->SetLabel(
"Stencil Buffer");
1265 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1266 ImGui::SliderInt(
"Stencil Write Value", &stencil_reference_write, 0,
1268 ImGui::SliderInt(
"Stencil Compare Value", &stencil_reference_read, 0,
1270 ImGui::Checkbox(
"Back face mode", &mirror);
1271 ImGui::ListBox(
"Front face compare function", ¤t_front_compare,
1273 ImGui::ListBox(
"Back face compare function", ¤t_back_compare,
1283 desc->SetStencilAttachmentDescriptors(front, back);
1284 auto pipeline =
context->GetPipelineLibrary()->GetPipeline(desc).Get();
1288 pass->SetCommandLabel(
"Box");
1290 pass->SetStencilReference(stencil_reference_read);
1291 pass->SetVertexBuffer(vertex_buffer);
1293 VS::UniformBuffer uniforms;
1294 EXPECT_EQ(pass->GetOrthographicTransform(),
1296 uniforms.mvp = pass->GetOrthographicTransform() *
1301 VS::BindUniformBuffer(*pass, data_host_buffer->EmplaceUniform(uniforms));
1303 FS::FrameInfo frame_info;
1304 frame_info.current_time = GetSecondsElapsed();
1305 frame_info.cursor_position = GetCursorPosition();
1306 frame_info.window_size.x = GetWindowSize().width;
1307 frame_info.window_size.y = GetWindowSize().height;
1309 FS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
1310 FS::BindContents1(*pass, boston, sampler);
1311 FS::BindContents2(*pass, bridge, sampler);
1312 if (!pass->Draw().ok()) {
1315 pass->EncodeCommands();
1318 if (!
context->GetCommandQueue()->Submit({buffer}).ok()) {
1321 data_host_buffer->Reset();
1329 auto cmd_buffer =
context->CreateCommandBuffer();
1330 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1331 GetContext()->GetResourceAllocator());
1333 auto render_target = render_target_cache->CreateOffscreen(
1335 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1337 EXPECT_EQ(
render_pass->GetSampleCount(), render_target.GetSampleCount());
1338 EXPECT_EQ(
render_pass->GetRenderTargetPixelFormat(),
1339 render_target.GetRenderTargetPixelFormat());
1341 render_target.GetStencilAttachment().has_value());
1343 render_target.GetRenderTargetSize());
1348 RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat) {
1350 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1351 GetContext()->GetResourceAllocator());
1353 RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1356 ->texture->GetTextureDescriptor()
1358 GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1361template <
class VertexShader,
class FragmentShader>
1363 const std::shared_ptr<Context>&
context) {
1365 auto pipeline_desc =
1366 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*
context);
1367 if (!pipeline_desc.has_value()) {
1371 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1373 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1382 using TextureVS = TextureVertexShader;
1383 using TextureFS = TextureFragmentShader;
1385 using SepiaVS = SepiaVertexShader;
1386 using SepiaFS = SepiaFragmentShader;
1391 if (!
context->GetCapabilities()->SupportsFramebufferFetch()) {
1392 GTEST_SKIP() <<
"This test uses framebuffer fetch and the backend doesn't "
1398 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(
context);
1399 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(
context);
1401 ASSERT_TRUE(texture_pipeline);
1402 ASSERT_TRUE(sepia_pipeline);
1407 {{100, 100, 0.0}, {0.0, 0.0}},
1408 {{800, 100, 0.0}, {1.0, 0.0}},
1409 {{800, 800, 0.0}, {1.0, 1.0}},
1410 {{100, 100, 0.0}, {0.0, 0.0}},
1411 {{800, 800, 0.0}, {1.0, 1.0}},
1412 {{100, 800, 0.0}, {0.0, 1.0}},
1425 auto boston = CreateTextureForFixture(
"boston.jpg");
1426 ASSERT_TRUE(boston);
1428 const auto& sampler =
context->GetSamplerLibrary()->GetSampler({});
1429 ASSERT_TRUE(sampler);
1433 context->GetCapabilities()->GetMinimumUniformAlignment());
1437 pass.SetPipeline(texture_pipeline);
1439 *
context->GetResourceAllocator()));
1440 TextureVS::UniformBuffer uniforms;
1443 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1444 TextureFS::BindTextureContents(pass, boston, sampler);
1445 if (!pass.Draw().ok()) {
1452 pass.SetPipeline(sepia_pipeline);
1454 *
context->GetResourceAllocator()));
1455 SepiaVS::UniformBuffer uniforms;
1458 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1459 if (!pass.Draw().ok()) {
1471 using TextureVS = TextureVertexShader;
1472 using TextureFS = TextureFragmentShader;
1474 using SwizzleVS = SepiaVertexShader;
1475 using SwizzleFS = SwizzleFragmentShader;
1477 using SepiaVS = SepiaVertexShader;
1478 using SepiaFS = SepiaFragmentShader;
1483 if (!
context->GetCapabilities()->SupportsFramebufferFetch()) {
1484 GTEST_SKIP() <<
"This test uses framebuffer fetch and the backend doesn't "
1490 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(
context);
1491 auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(
context);
1492 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(
context);
1494 ASSERT_TRUE(texture_pipeline);
1495 ASSERT_TRUE(swizzle_pipeline);
1496 ASSERT_TRUE(sepia_pipeline);
1501 {{100, 100, 0.0}, {0.0, 0.0}},
1502 {{800, 100, 0.0}, {1.0, 0.0}},
1503 {{800, 800, 0.0}, {1.0, 1.0}},
1504 {{100, 100, 0.0}, {0.0, 0.0}},
1505 {{800, 800, 0.0}, {1.0, 1.0}},
1506 {{100, 800, 0.0}, {0.0, 1.0}},
1519 auto boston = CreateTextureForFixture(
"boston.jpg");
1520 ASSERT_TRUE(boston);
1522 const auto& sampler =
context->GetSamplerLibrary()->GetSampler({});
1523 ASSERT_TRUE(sampler);
1527 context->GetCapabilities()->GetMinimumUniformAlignment());
1531 pass.SetPipeline(texture_pipeline);
1533 *
context->GetResourceAllocator()));
1534 TextureVS::UniformBuffer uniforms;
1537 TextureVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1538 TextureFS::BindTextureContents(pass, boston, sampler);
1539 if (!pass.Draw().ok()) {
1546 pass.SetPipeline(sepia_pipeline);
1548 *
context->GetResourceAllocator()));
1549 SepiaVS::UniformBuffer uniforms;
1552 SepiaVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1553 if (!pass.Draw().ok()) {
1560 pass.SetPipeline(swizzle_pipeline);
1562 *
context->GetResourceAllocator()));
1563 SwizzleVS::UniformBuffer uniforms;
1566 SwizzleVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1567 if (!pass.Draw().ok()) {
1578 using FS = BoxFadeFragmentShader;
1588 EXPECT_FALSE(FS::BindContents2(*pass,
nullptr, sampler));
1602 desc.
size = {100, 100};
1604 auto texture =
context->GetResourceAllocator()->CreateTexture(desc);
1618 ASSERT_TRUE(pass && pass->IsValid());
1619 pass->EncodeCommands();
1620 EXPECT_TRUE(
context->GetCommandQueue()->Submit({buffer}).ok());
1629 GTEST_SKIP() <<
"Rendering to non-zero mip levels is gated on a GLES "
1630 "capability; covered by the Metal and Vulkan backends.";
1638 desc.
size = {100, 100};
1641 auto texture =
context->GetResourceAllocator()->CreateTexture(desc);
1653 EXPECT_EQ(
target.GetRenderTargetSize(),
ISize(50, 50));
1657 ASSERT_TRUE(pass && pass->IsValid());
1658 pass->EncodeCommands();
1659 EXPECT_TRUE(
context->GetCommandQueue()->Submit({buffer}).ok());
1670 desc.
size = {100, 100};
1673 auto texture =
context->GetResourceAllocator()->CreateTexture(desc);
1680 EXPECT_TRUE(color0.
IsValid());
1686 EXPECT_FALSE(color0.
IsValid());
1690 EXPECT_FALSE(color0.
IsValid());
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::function< bool(RenderTarget &render_target)> RenderCallback
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.
const Matrix & GetOrthographicTransform() const
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
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.
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
const std::optional< DepthAttachment > & GetDepthAttachment() const
size_t GetVertexCount() const
size_t GetIndexCount() const
VertexBuffer CreateVertexBuffer(HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer) const
VertexBufferBuilder & AppendIndex(IndexType_ index)
void SetLabel(const std::string &label)
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
constexpr impeller::IndexType GetIndexType() const
A wrapper around a raw ptr that adds additional unopt mode only checks.
CompareFunction FunctionOf(int index) const
const char *const * labels() const
int IndexOf(CompareFunction func) const
FlutterDesktopBinaryReply callback
#define FML_UNREACHABLE()
std::shared_ptr< ImpellerAllocator > allocator
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
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 disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
PlaygroundTest RendererTest
static const CompareFunctionUIData & CompareFunctionUI()
TEST_P(AiksTest, DrawAtlasNoColor)
@ kNone
Does not use the index buffer.
LinePipeline::FragmentShader FS
@ 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.
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.
LinePipeline::VertexShader VS
static std::unique_ptr< PipelineT > CreateDefaultPipeline(const Context &context)
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.
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
std::shared_ptr< ContextGLES > context
std::shared_ptr< RenderPass > render_pass
std::shared_ptr< PipelineGLES > pipeline
std::shared_ptr< CommandBuffer > command_buffer
std::shared_ptr< Texture > texture
static constexpr Color Red()
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
static constexpr Color Green()
static constexpr Matrix MakeOrthographic(TSize< T > size)
static constexpr Matrix MakeTranslation(const Vector3 &t)
static Matrix MakeRotationY(Radians r)
static Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
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...