Added support for Canvas#drawDoubleRoundRect in application Canvas API

Exposed Skia's underlying drawDRRect method used to draw a double
rounded rectangle

Bug: 117181396
Test: Added test case to verify Canvas#drawDRRect and re-ran CanvasTests
Change-Id: I4e1954c8ffc82811dc541488d1df9b37309faf51
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 17f1a3b..2e5aef5 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -504,6 +504,11 @@
     mCanvas->drawRoundRect(rect, rx, ry, *filterPaint(paint));
 }
 
+void SkiaCanvas::drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+                                const SkPaint& paint) {
+    mCanvas->drawDRRect(outer, inner, *filterPaint(paint));
+}
+
 void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
     if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return;
     mCanvas->drawCircle(x, y, radius, *filterPaint(paint));
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 24b7ec6..3a877cf 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -107,6 +107,10 @@
     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
                                const SkPaint& paint) override;
+
+   virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+                               const SkPaint& paint) override;
+
     virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
     virtual void drawOval(float left, float top, float right, float bottom,
                           const SkPaint& paint) override;
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index af7f013..e2ea2bc 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -178,6 +178,41 @@
     MinikinUtils::forFontRun(layout, &paint, f);
 }
 
+void Canvas::drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight,
+                            float outerBottom, float outerRx, float outerRy, float innerLeft,
+                            float innerTop, float innerRight, float innerBottom, float innerRx,
+                            float innerRy, const SkPaint& paint) {
+    if (CC_UNLIKELY(paint.nothingToDraw())) return;
+    SkRect outer = SkRect::MakeLTRB(outerLeft, outerTop, outerRight, outerBottom);
+    SkRect inner = SkRect::MakeLTRB(innerLeft, innerTop, innerRight, innerBottom);
+
+    SkRRect outerRRect;
+    outerRRect.setRectXY(outer, outerRx, outerRy);
+
+    SkRRect innerRRect;
+    innerRRect.setRectXY(inner, innerRx, innerRy);
+    drawDoubleRoundRect(outerRRect, innerRRect, paint);
+}
+
+void Canvas::drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight,
+                            float outerBottom, const float* outerRadii, float innerLeft,
+                            float innerTop, float innerRight, float innerBottom,
+                            const float* innerRadii, const SkPaint& paint) {
+    static_assert(sizeof(SkVector) == sizeof(float) * 2);
+    if (CC_UNLIKELY(paint.nothingToDraw())) return;
+    SkRect outer = SkRect::MakeLTRB(outerLeft, outerTop, outerRight, outerBottom);
+    SkRect inner = SkRect::MakeLTRB(innerLeft, innerTop, innerRight, innerBottom);
+
+    SkRRect outerRRect;
+    const SkVector* outerSkVector = reinterpret_cast<const SkVector*>(outerRadii);
+    outerRRect.setRectRadii(outer, outerSkVector);
+
+    SkRRect innerRRect;
+    const SkVector* innerSkVector = reinterpret_cast<const SkVector*>(innerRadii);
+    innerRRect.setRectRadii(inner, innerSkVector);
+    drawDoubleRoundRect(outerRRect, innerRRect, paint);
+}
+
 class DrawTextOnPathFunctor {
 public:
     DrawTextOnPathFunctor(const minikin::Layout& layout, Canvas* canvas, float hOffset,
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index b9af7de2..e99742b 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -236,6 +236,8 @@
     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0;
     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
                                const SkPaint& paint) = 0;
+    virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+                                const SkPaint& paint) = 0;
     virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0;
     virtual void drawOval(float left, float top, float right, float bottom,
                           const SkPaint& paint) = 0;
@@ -284,6 +286,16 @@
                         const SkPath& path, float hOffset, float vOffset, const Paint& paint,
                         const Typeface* typeface);
 
+    void drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight,
+                                float outerBottom, float outerRx, float outerRy, float innerLeft,
+                                float innerTop, float innerRight, float innerBottom, float innerRx,
+                                float innerRy, const SkPaint& paint);
+
+    void drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight,
+                                float outerBottom, const float* outerRadii, float innerLeft,
+                                float innerTop, float innerRight, float innerBottom,
+                                const float* innerRadii, const SkPaint& paint);
+
     static int GetApiLevel() { return sApiLevel; }
 
 protected: