Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | List of all members
ClipSuperRRect Class Reference
Inheritance diagram for ClipSuperRRect:
RuntimeShaderGM skiagm::GM

Public Member Functions

 ClipSuperRRect (const char *name, float power)
 
void drawSuperRRect (SkCanvas *canvas, const SkRect &superRRect, float radX, float radY, SkColor color)
 
void onDraw (SkCanvas *canvas) override
 
- Public Member Functions inherited from RuntimeShaderGM
 RuntimeShaderGM (const char *name, SkISize size, const char *sksl, uint32_t flags=0)
 
void onOnceBeforeDraw () override
 
bool runAsBench () const override
 
SkString getName () const override
 
SkISize getISize () override
 
bool onAnimate (double nanos) override
 
- Public Member Functions inherited from skiagm::GM
 GM (SkColor backgroundColor=SK_ColorWHITE)
 
virtual ~GM ()
 
void setMode (Mode mode)
 
Mode getMode () const
 
DrawResult gpuSetup (SkCanvas *, SkString *errorMsg, GraphiteTestContext *=nullptr)
 
void gpuTeardown ()
 
void onceBeforeDraw ()
 
DrawResult draw (SkCanvas *canvas)
 
DrawResult draw (SkCanvas *, SkString *errorMsg)
 
void drawBackground (SkCanvas *)
 
DrawResult drawContent (SkCanvas *canvas)
 
DrawResult drawContent (SkCanvas *, SkString *errorMsg)
 
SkScalar width ()
 
SkScalar height ()
 
SkColor getBGColor () const
 
void setBGColor (SkColor)
 
void drawSizeBounds (SkCanvas *, SkColor)
 
bool animate (double)
 
virtual bool onChar (SkUnichar)
 
bool getControls (SkMetaData *controls)
 
void setControls (const SkMetaData &controls)
 
virtual void modifyGrContextOptions (GrContextOptions *)
 
virtual void modifyGraphiteContextOptions (skgpu::graphite::ContextOptions *) const
 
virtual bool isBazelOnly () const
 
virtual std::map< std::string, std::string > getGoldKeys () const
 

Additional Inherited Members

- Public Types inherited from skiagm::GM
enum  Mode { kGM_Mode , kSample_Mode , kBench_Mode }
 
using DrawResult = skiagm::DrawResult
 
using GraphiteTestContext = skiatest::graphite::GraphiteTestContext
 
- Static Public Attributes inherited from skiagm::GM
static constexpr char kErrorMsg_DrawSkippedGpuOnly []
 
- Protected Member Functions inherited from skiagm::GM
virtual DrawResult onGpuSetup (SkCanvas *, SkString *, GraphiteTestContext *)
 
virtual void onGpuTeardown ()
 
virtual DrawResult onDraw (SkCanvas *, SkString *errorMsg)
 
virtual bool onGetControls (SkMetaData *)
 
virtual void onSetControls (const SkMetaData &)
 
GraphiteTestContextgraphiteTestContext () const
 
- Protected Attributes inherited from RuntimeShaderGM
SkString fName
 
SkISize fSize
 
uint32_t fFlags
 
float fSecs = 0.0f
 
SkString fSkSL
 
sk_sp< SkRuntimeEffectfEffect
 

Detailed Description

Definition at line 441 of file runtimeshader.cpp.

Constructor & Destructor Documentation

◆ ClipSuperRRect()

ClipSuperRRect::ClipSuperRRect ( const char *  name,
float  power 
)
inline

Definition at line 443 of file runtimeshader.cpp.

443 : RuntimeShaderGM(name, {500, 500}, R"(
444 uniform float power_minus1;
445 uniform float2 stretch_factor;
446 uniform float2x2 derivatives;
447 half4 main(float2 xy) {
448 xy = max(abs(xy) + stretch_factor, 0);
449 float2 exp_minus1 = pow(xy, power_minus1.xx); // If power == 3.5: xy * xy * sqrt(xy)
450 float f = dot(exp_minus1, xy) - 1; // f = x^n + y^n - 1
451 float2 grad = exp_minus1 * derivatives;
452 float fwidth = abs(grad.x) + abs(grad.y) + 1e-12; // 1e-12 to avoid a divide by zero.
453 return half4(saturate(.5 - f/fwidth)); // Approx coverage by riding the gradient to f=0.
454 }
455 )"), fPower(power) {}
const char * name
Definition fuchsia.cc:50

Member Function Documentation

◆ drawSuperRRect()

void ClipSuperRRect::drawSuperRRect ( SkCanvas canvas,
const SkRect superRRect,
float  radX,
float  radY,
SkColor  color 
)
inline

Definition at line 457 of file runtimeshader.cpp.

458 {
460 paint.setColor(color);
461
462 if (fPower == 2) {
463 // Draw a normal round rect for the sake of testing.
464 SkRRect rrect = SkRRect::MakeRectXY(superRRect, radX, radY);
465 paint.setAntiAlias(true);
466 canvas->drawRRect(rrect, paint);
467 return;
468 }
469
471 builder.uniform("power_minus1") = fPower - 1;
472
473 // Size the corners such that the "apex" of our "super" rounded corner is in the same
474 // location that the apex of a circular rounded corner would be with the given radii. We
475 // define the apex as the point on the rounded corner that is 45 degrees between the
476 // horizontal and vertical edges.
477 float scale = (1 - SK_ScalarRoot2Over2) / (1 - exp2f(-1/fPower));
478 float cornerWidth = radX * scale;
479 float cornerHeight = radY * scale;
480 cornerWidth = std::min(cornerWidth, superRRect.width() * .5f);
481 cornerHeight = std::min(cornerHeight, superRRect.height() * .5f);
482 // The stretch factor controls how long the flat edge should be between rounded corners.
483 builder.uniform("stretch_factor") = SkV2{1 - superRRect.width()*.5f / cornerWidth,
484 1 - superRRect.height()*.5f / cornerHeight};
485
486 // Calculate a 2x2 "derivatives" matrix that the shader will use to find the gradient.
487 //
488 // f = s^n + t^n - 1 [s,t are "super" rounded corner coords in normalized 0..1 space]
489 //
490 // gradient = [df/dx df/dy] = [ns^(n-1) nt^(n-1)] * |ds/dx ds/dy|
491 // |dt/dx dt/dy|
492 //
493 // = [s^(n-1) t^(n-1)] * |n 0| * |ds/dx ds/dy|
494 // |0 n| |dt/dx dt/dy|
495 //
496 // = [s^(n-1) t^(n-1)] * |2n/cornerWidth 0| * mat2x2(canvasMatrix)^-1
497 // |0 2n/cornerHeight|
498 //
499 // = [s^(n-1) t^(n-1)] * "derivatives"
500 //
501 const SkMatrix& M = canvas->getTotalMatrix();
502 float a=M.getScaleX(), b=M.getSkewX(), c=M.getSkewY(), d=M.getScaleY();
503 float determinant = a*d - b*c;
504 float dx = fPower / (cornerWidth * determinant);
505 float dy = fPower / (cornerHeight * determinant);
506 builder.uniform("derivatives") = SkV4{d*dx, -c*dy, -b*dx, a*dy};
507
508 // This matrix will be inverted by the effect system, giving a matrix that converts local
509 // coordinates to (almost) coner coordinates. To get the rest of the way to the nearest
510 // corner's space, the shader will have to take the absolute value, add the stretch_factor,
511 // then clamp above zero.
512 SkMatrix cornerToLocal;
513 cornerToLocal.setScaleTranslate(cornerWidth, cornerHeight, superRRect.centerX(),
514 superRRect.centerY());
515 canvas->clipShader(builder.makeShader(&cornerToLocal));
516
517 // Bloat the outer edges of the rect we will draw so it contains all the antialiased pixels.
518 // Bloat by a full pixel instead of half in case Skia is in a mode that draws this rect with
519 // unexpected AA of its own.
520 float inverseDet = 1 / fabsf(determinant);
521 float bloatX = (fabsf(d) + fabsf(c)) * inverseDet;
522 float bloatY = (fabsf(b) + fabsf(a)) * inverseDet;
523 canvas->drawRect(superRRect.makeOutset(bloatX, bloatY), paint);
524 }
SkColor4f color
#define SK_ScalarRoot2Over2
Definition SkScalar.h:23
sk_sp< SkRuntimeEffect > fEffect
void drawRect(const SkRect &rect, const SkPaint &paint)
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
SkMatrix getTotalMatrix() const
void clipShader(sk_sp< SkShader >, SkClipOp=SkClipOp::kIntersect)
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Definition SkMatrix.h:1803
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition SkRRect.h:180
const Paint & paint
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
static bool b
struct MyStruct a[10]
SkRRect rrect
Definition SkRecords.h:232
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition SkRecords.h:208
#define M(PROC, DITHER)
const Scalar scale
SkRect makeOutset(float dx, float dy) const
Definition SkRect.h:1002
constexpr float centerX() const
Definition SkRect.h:776
constexpr float height() const
Definition SkRect.h:769
constexpr float centerY() const
Definition SkRect.h:785
constexpr float width() const
Definition SkRect.h:762
Definition SkM44.h:19
Definition SkM44.h:98

◆ onDraw()

void ClipSuperRRect::onDraw ( SkCanvas canvas)
inlineoverridevirtual

Reimplemented from skiagm::GM.

Definition at line 526 of file runtimeshader.cpp.

526 {
527 SkRandom rand(2);
528
529 canvas->save();
530 canvas->translate(canvas->imageInfo().width() / 2.f, canvas->imageInfo().height() / 2.f);
531
532 canvas->save();
533 canvas->rotate(21);
534 this->drawSuperRRect(canvas, SkRect::MakeXYWH(-5, 25, 175, 100), 50, 30,
535 rand.nextU() | 0xff808080);
536 canvas->restore();
537
538 canvas->save();
539 canvas->rotate(94);
540 this->drawSuperRRect(canvas, SkRect::MakeXYWH(95, 75, 125, 100), 30, 30,
541 rand.nextU() | 0xff808080);
542 canvas->restore();
543
544 canvas->save();
545 canvas->rotate(132);
546 this->drawSuperRRect(canvas, SkRect::MakeXYWH(0, 75, 150, 100), 40, 30,
547 rand.nextU() | 0xff808080);
548 canvas->restore();
549
550 canvas->save();
551 canvas->rotate(282);
552 this->drawSuperRRect(canvas, SkRect::MakeXYWH(15, -20, 100, 100), 20, 20,
553 rand.nextU() | 0xff808080);
554 canvas->restore();
555
556 canvas->save();
557 canvas->rotate(0);
558 this->drawSuperRRect(canvas, SkRect::MakeXYWH(140, -50, 90, 110), 25, 25,
559 rand.nextU() | 0xff808080);
560 canvas->restore();
561
562 canvas->save();
563 canvas->rotate(-35);
564 this->drawSuperRRect(canvas, SkRect::MakeXYWH(160, -60, 60, 90), 18, 18,
565 rand.nextU() | 0xff808080);
566 canvas->restore();
567
568 canvas->save();
569 canvas->rotate(65);
570 this->drawSuperRRect(canvas, SkRect::MakeXYWH(220, -120, 60, 90), 18, 18,
571 rand.nextU() | 0xff808080);
572 canvas->restore();
573
574 canvas->save();
575 canvas->rotate(265);
576 this->drawSuperRRect(canvas, SkRect::MakeXYWH(150, -129, 80, 160), 24, 39,
577 rand.nextU() | 0xff808080);
578 canvas->restore();
579
580 canvas->restore();
581 }
void drawSuperRRect(SkCanvas *canvas, const SkRect &superRRect, float radX, float radY, SkColor color)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void rotate(SkScalar degrees)
int save()
Definition SkCanvas.cpp:451
SkImageInfo imageInfo() const
int width() const
int height() const
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659

The documentation for this class was generated from the following file: