2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ #include < numeric>
6
+
5
7
#include " flutter/fml/synchronization/waitable_event.h"
6
8
#include " flutter/fml/time/time_point.h"
7
9
#include " flutter/testing/testing.h"
8
10
#include " gmock/gmock.h"
9
11
#include " impeller/base/strings.h"
12
+ #include " impeller/entity/contents/content_context.h"
10
13
#include " impeller/fixtures/cubic_to_quads.comp.h"
11
14
#include " impeller/fixtures/golden_heart.h"
12
15
#include " impeller/fixtures/quad_polyline.comp.h"
22
25
#include " impeller/renderer/compute_pipeline_builder.h"
23
26
#include " impeller/renderer/formats.h"
24
27
#include " impeller/renderer/pipeline_library.h"
28
+ #include " impeller/renderer/render_pass.h"
25
29
26
30
namespace impeller {
27
31
namespace testing {
@@ -44,27 +48,21 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {
44
48
static constexpr size_t kCubicCount = 6 ;
45
49
static constexpr Scalar kAccuracy = .1 ;
46
50
47
- DeviceBufferDescriptor quad_buffer_desc;
48
- quad_buffer_desc.storage_mode = StorageMode::kHostVisible ;
49
- quad_buffer_desc.size = sizeof (CS::Quads<kCubicCount * 10 >);
50
- auto quads = context->GetResourceAllocator ()->CreateBuffer (quad_buffer_desc);
51
- quads->SetLabel (" Quads" );
51
+ auto quads = CreateHostVisibleDeviceBuffer<CS::Quads<kCubicCount * 10 >>(
52
+ context, " Quads" );
52
53
53
- DeviceBufferDescriptor point_buffer_desc;
54
- point_buffer_desc.storage_mode = StorageMode::kHostVisible ;
55
54
// TODO(dnfield): Size this buffer more accurately.
56
- point_buffer_desc.size = sizeof (QS::Polyline<kCubicCount * 10 * 10 >);
57
55
auto polyline =
58
- context->GetResourceAllocator ()->CreateBuffer (point_buffer_desc);
59
- polyline->SetLabel (" polyline" );
56
+ CreateHostVisibleDeviceBuffer<QS::Polyline<kCubicCount * 10 * 10 >>(
57
+ context, " polyline" );
58
+
59
+ auto vertex_buffer_count =
60
+ CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
61
+ " VertexBufferCount" );
60
62
61
- DeviceBufferDescriptor vertex_buffer_desc;
62
- vertex_buffer_desc.storage_mode = StorageMode::kHostVisible ;
63
63
// TODO(dnfield): Size this buffer more accurately.
64
- vertex_buffer_desc.size = sizeof (SS::VertexBuffer<kCubicCount * 10 * 10 * 4 >);
65
- auto vertex_buffer =
66
- context->GetResourceAllocator ()->CreateBuffer (vertex_buffer_desc);
67
- vertex_buffer->SetLabel (" VertexBuffer" );
64
+ auto vertex_buffer = CreateHostVisibleDeviceBuffer<
65
+ SS::VertexBuffer<kCubicCount * 10 * 10 * 4 >>(context, " VertexBuffer" );
68
66
69
67
{
70
68
using CubicPipelineBuilder = ComputePipelineBuilder<CS>;
@@ -138,13 +136,14 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {
138
136
pass->SetThreadGroupSize (ISize (1024 , 1 ));
139
137
140
138
ComputeCommand cmd;
141
- cmd.label = " Stroke" ;
139
+ cmd.label = " Draw Stroke" ;
142
140
cmd.pipeline = compute_pipeline;
143
141
144
142
SS::Config config{.width = 1 .0f , .cap = 1 , .join = 1 , .miter_limit = 4 .0f };
145
143
SS::BindConfig (cmd, pass->GetTransientsBuffer ().EmplaceUniform (config));
146
144
147
145
SS::BindPolyline (cmd, polyline->AsBufferView ());
146
+ SS::BindVertexBufferCount (cmd, vertex_buffer_count->AsBufferView ());
148
147
SS::BindVertexBuffer (cmd, vertex_buffer->AsBufferView ());
149
148
150
149
ASSERT_TRUE (pass->AddCommand (std::move (cmd)));
@@ -154,7 +153,7 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {
154
153
155
154
fml::AutoResetWaitableEvent latch;
156
155
ASSERT_TRUE (cmd_buffer->SubmitCommands ([&latch, quads, polyline,
157
- vertex_buffer](
156
+ vertex_buffer_count, vertex_buffer](
158
157
CommandBuffer::Status status) {
159
158
EXPECT_EQ (status, CommandBuffer::Status::kCompleted );
160
159
@@ -183,7 +182,9 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {
183
182
184
183
auto * v = reinterpret_cast <SS::VertexBuffer<kCubicCount * 10 * 10 * 4 >*>(
185
184
vertex_buffer->AsBufferView ().contents );
186
- EXPECT_EQ (v->count , golden_heart_vertices.size ());
185
+ auto * v_count = reinterpret_cast <SS::VertexBufferCount*>(
186
+ vertex_buffer_count->AsBufferView ().contents );
187
+ EXPECT_EQ (v_count->count , golden_heart_vertices.size ());
187
188
for (size_t i = 0 ; i < golden_heart_vertices.size (); i += 1 ) {
188
189
EXPECT_LT (std::abs (golden_heart_vertices[i].x - v->position [i].x ), 1e-3 );
189
190
EXPECT_LT (std::abs (golden_heart_vertices[i].y - v->position [i].y ), 1e-3 );
@@ -193,6 +194,64 @@ TEST_P(ComputeTest, HeartCubicsToStrokeVertices) {
193
194
}));
194
195
195
196
latch.Wait ();
197
+
198
+ auto callback = [&](RenderPass& pass) -> bool {
199
+ ContentContext renderer (context);
200
+ if (!renderer.IsValid ()) {
201
+ return false ;
202
+ }
203
+
204
+ using VS = SolidFillPipeline::VertexShader;
205
+ using FS = SolidFillPipeline::FragmentShader;
206
+
207
+ Command cmd;
208
+ cmd.label = " Draw Stroke" ;
209
+ cmd.stencil_reference = 0 ; // entity.GetStencilDepth();
210
+
211
+ ContentContextOptions options;
212
+ options.sample_count = pass.GetRenderTarget ().GetSampleCount ();
213
+ options.color_attachment_pixel_format =
214
+ pass.GetRenderTarget ().GetRenderTargetPixelFormat ();
215
+ options.has_stencil_attachment =
216
+ pass.GetRenderTarget ().GetStencilAttachment ().has_value ();
217
+ options.blend_mode = BlendMode::kSourceIn ; // entity.GetBlendMode();
218
+ options.primitive_type = PrimitiveType::kTriangleStrip ;
219
+ options.stencil_compare = CompareFunction::kEqual ;
220
+ options.stencil_operation = StencilOperation::kIncrementClamp ;
221
+
222
+ cmd.pipeline = renderer.GetSolidFillPipeline (options);
223
+
224
+ auto count = golden_heart_vertices.size ();
225
+ auto & host_buffer = pass.GetTransientsBuffer ();
226
+ std::vector<uint16_t > indices (count);
227
+ std::iota (std::begin (indices), std::end (indices), 0 );
228
+
229
+ VertexBuffer render_vertex_buffer{
230
+ .vertex_buffer = vertex_buffer->AsBufferView (),
231
+ .index_buffer = host_buffer.Emplace (
232
+ indices.data (), count * sizeof (uint16_t ), alignof (uint16_t )),
233
+ .index_count = count,
234
+ .index_type = IndexType::k16bit};
235
+ cmd.BindVertices (render_vertex_buffer);
236
+
237
+ VS::FrameInfo frame_info;
238
+ auto world_matrix = Matrix::MakeScale (GetContentScale ());
239
+ frame_info.mvp =
240
+ Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) * world_matrix;
241
+ VS::BindFrameInfo (cmd,
242
+ pass.GetTransientsBuffer ().EmplaceUniform (frame_info));
243
+
244
+ FS::FragInfo frag_info;
245
+ frag_info.color = Color::Red ().Premultiply ();
246
+ FS::BindFragInfo (cmd, pass.GetTransientsBuffer ().EmplaceUniform (frag_info));
247
+
248
+ if (!pass.AddCommand (std::move (cmd))) {
249
+ return false ;
250
+ }
251
+
252
+ return true ;
253
+ };
254
+ ASSERT_TRUE (OpenPlaygroundHere (callback));
196
255
}
197
256
198
257
TEST_P (ComputeTest, QuadsToPolyline) {
@@ -215,12 +274,8 @@ TEST_P(ComputeTest, QuadsToPolyline) {
215
274
golden_heart_quads[i].p2 };
216
275
}
217
276
218
- DeviceBufferDescriptor point_buffer_desc;
219
- point_buffer_desc.storage_mode = StorageMode::kHostVisible ;
220
- point_buffer_desc.size = sizeof (QS::Polyline<kPolylineCount >);
221
- auto polyline =
222
- context->GetResourceAllocator ()->CreateBuffer (point_buffer_desc);
223
- polyline->SetLabel (" polyline" );
277
+ auto polyline = CreateHostVisibleDeviceBuffer<QS::Polyline<kPolylineCount >>(
278
+ context, " polyline" );
224
279
225
280
{
226
281
using QuadPipelineBuilder = ComputePipelineBuilder<QS>;
0 commit comments