@@ -335,6 +335,86 @@ void BM_DrawRRect(benchmark::State& state,
335335 canvas_provider->Snapshot (filename);
336336}
337337
338+ // Draws a series of "DR" rects of the requested width across
339+ // the canvas and repeats until `kRRectsToDraw` rects have been drawn.
340+ //
341+ // A "DR" rect is a shape consisting of the difference between two
342+ // rounded rects.
343+ //
344+ // Half the drawn DR rects will not have an integral offset.
345+ void BM_DrawDRRect (benchmark::State& state,
346+ BackendType backend_type,
347+ unsigned attributes,
348+ SkRRect::Type type) {
349+ auto canvas_provider = CreateCanvasProvider (backend_type);
350+ DisplayListBuilder builder;
351+ builder.setAttributesFromPaint (GetPaintForRun (attributes),
352+ DisplayListOpFlags::kDrawDRRectFlags );
353+ AnnotateAttributes (attributes, state, DisplayListOpFlags::kDrawDRRectFlags );
354+
355+ size_t length = state.range (0 );
356+ size_t canvas_size = length * 2 ;
357+ canvas_provider->InitializeSurface (canvas_size, canvas_size);
358+ auto canvas = canvas_provider->GetSurface ()->getCanvas ();
359+
360+ SkVector radii[4 ];
361+ switch (type) {
362+ case SkRRect::Type::kSimple_Type :
363+ radii[0 ] = SkVector::Make (5 .0f , 5 .0f );
364+ radii[1 ] = SkVector::Make (5 .0f , 5 .0f );
365+ radii[2 ] = SkVector::Make (5 .0f , 5 .0f );
366+ radii[3 ] = SkVector::Make (5 .0f , 5 .0f );
367+ break ;
368+ case SkRRect::Type::kNinePatch_Type :
369+ radii[0 ] = SkVector::Make (5 .0f , 7 .0f );
370+ radii[1 ] = SkVector::Make (3 .0f , 7 .0f );
371+ radii[2 ] = SkVector::Make (3 .0f , 4 .0f );
372+ radii[3 ] = SkVector::Make (5 .0f , 4 .0f );
373+ break ;
374+ case SkRRect::Type::kComplex_Type :
375+ radii[0 ] = SkVector::Make (5 .0f , 4 .0f );
376+ radii[1 ] = SkVector::Make (4 .0f , 5 .0f );
377+ radii[2 ] = SkVector::Make (3 .0f , 6 .0f );
378+ radii[3 ] = SkVector::Make (8 .0f , 7 .0f );
379+ break ;
380+ default :
381+ break ;
382+ }
383+
384+ const SkScalar offset = 0 .5f ;
385+ const SkScalar multiplier = length / 16 .0f ;
386+ SkRRect rrect, rrect_2;
387+
388+ SkVector set_radii[4 ];
389+ for (size_t i = 0 ; i < 4 ; i++) {
390+ set_radii[i] = radii[i] * multiplier;
391+ }
392+ rrect.setRectRadii (SkRect::MakeLTRB (0 , 0 , length, length), set_radii);
393+
394+ for (size_t i = 0 ; i < kRRectsToDraw ; i++) {
395+ rrect.inset (0 .1f * length, 0 .1f * length, &rrect_2);
396+ builder.drawDRRect (rrect, rrect_2);
397+ rrect.offset (offset, offset);
398+ if (rrect.rect ().right () > canvas_size) {
399+ rrect.offset (-canvas_size, 0 );
400+ }
401+ if (rrect.rect ().bottom () > canvas_size) {
402+ rrect.offset (0 , -canvas_size);
403+ }
404+ }
405+ auto display_list = builder.Build ();
406+
407+ // We only want to time the actual rasterization.
408+ for (auto _ : state) {
409+ display_list->RenderTo (canvas);
410+ canvas_provider->GetSurface ()->flushAndSubmit (true );
411+ }
412+
413+ auto filename = canvas_provider->BackendName () + " -DrawDRRect-" +
414+ std::to_string (state.range (0 )) + " .png" ;
415+ canvas_provider->Snapshot (filename);
416+ }
417+
338418void BM_DrawArc (benchmark::State& state,
339419 BackendType backend_type,
340420 unsigned attributes) {
0 commit comments