SkCanvas::drawPatch param SkPoint[12]

drawPatch now receives as parameter const SkPoint cubics[12]

Adjusted derived classes and serialization.

Ajusted GM's and benches that take into account combinations of optional
parameters, the scale of the patch and 4 different types of patches.

Planning on adding the extra functionality of SkPatch in another CL.

BUG=skia:
R=egdaniel@google.com, reed@google.com

Author: dandov@google.com

Review URL: https://codereview.chromium.org/463493002
diff --git a/bench/PatchBench.cpp b/bench/PatchBench.cpp
new file mode 100644
index 0000000..2e99e4e
--- /dev/null
+++ b/bench/PatchBench.cpp
@@ -0,0 +1,325 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "Benchmark.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkColorPriv.h"
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+#include "SkPatchUtils.h"
+#include "SkRandom.h"
+#include "SkShader.h"
+#include "SkString.h"
+#include "SkTArray.h"
+
+class PatchBench : public Benchmark {
+    
+public:
+    
+    enum VertexMode {
+        kNone_VertexMode,
+        kColors_VertexMode,
+        kTexCoords_VertexMode,
+        kBoth_VertexMode
+    };
+    
+    PatchBench(SkPoint scale, VertexMode vertexMode)
+    : fScale(scale)
+    , fVertexMode(vertexMode) { }
+
+    // to add name of specific class override this method
+    virtual void appendName(SkString* name) {
+        name->append("normal");
+    }
+    
+    // to make other type of patches override this method
+    virtual void setCubics() {
+        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
+            //top points
+            {100,100},{150,50},{250,150}, {300,100},
+            //right points
+            {350, 150},{250,200},
+            //bottom points
+            {300,300},{250,250},{150,350},{100,300},
+            //left points
+            {50,250},{150,50}
+        };
+        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
+    }
+    
+    virtual void setColors() {
+        const SkColor colors[SkPatchUtils::kNumCorners] = {
+            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
+        };
+        memcpy(fColors, colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
+    }
+    
+    virtual void setTexCoords() {
+        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
+            {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f,1.0f}, {0.0f, 1.0f}
+        };
+        memcpy(fTexCoords, texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
+    }
+    
+    // override this method to change the shader
+    virtual SkShader* getShader() {
+        const SkColor colors[] = {
+            SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
+            SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
+        };
+        const SkPoint pts[] = { { 200.f / 4.f, 0.f }, { 3.f * 200.f / 4, 200.f } };
+        
+        return SkGradientShader::CreateLinear(pts, colors, NULL,
+                                              SK_ARRAY_COUNT(colors),
+                                              SkShader::kMirror_TileMode);
+    }
+
+protected:
+    virtual const char* onGetName() SK_OVERRIDE {
+        SkString vertexMode;
+        switch (fVertexMode) {
+            case kNone_VertexMode:
+                vertexMode.set("meshlines");
+                break;
+            case kColors_VertexMode:
+                vertexMode.set("colors");
+                break;
+            case kTexCoords_VertexMode:
+                vertexMode.set("texs");
+                break;
+            case kBoth_VertexMode:
+                vertexMode.set("colors&texs");
+                break;
+            default:
+                break;
+        }
+        SkString type;
+        this->appendName(&type);
+        fName.printf("patch_%s_%s_[%f,%f]", type.c_str(), vertexMode.c_str(),
+                    fScale.x(), fScale.y());
+        return fName.c_str();
+    }
+    
+    virtual void preDraw() {
+        
+    }
+
+    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
+        
+        this->setCubics();
+        this->setColors();
+        this->setTexCoords();
+        this->setupPaint(&fPaint);
+        switch (fVertexMode) {
+            case kTexCoords_VertexMode:
+            case kBoth_VertexMode:
+                fPaint.setShader(getShader());
+                break;
+            default:
+                fPaint.setShader(NULL);
+                break;
+        }
+        
+        canvas->scale(fScale.x(), fScale.y());
+        for (int i = 0; i < loops; i++) {
+            switch (fVertexMode) {
+                case kNone_VertexMode:
+                    canvas->drawPatch(fCubics, NULL, NULL, NULL, fPaint);
+                    break;
+                case kColors_VertexMode:
+                    canvas->drawPatch(fCubics, fColors, NULL, NULL, fPaint);
+                    break;
+                case kTexCoords_VertexMode:
+                    canvas->drawPatch(fCubics, NULL, fTexCoords, NULL, fPaint);
+                    break;
+                case kBoth_VertexMode:
+                    canvas->drawPatch(fCubics, fColors, fTexCoords, NULL, fPaint);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    SkPaint     fPaint;
+    SkString    fName;
+    SkVector    fScale;
+    SkPoint     fCubics[12];
+    SkPoint     fTexCoords[4];
+    SkColor     fColors[4];
+    VertexMode  fVertexMode;
+    
+    typedef Benchmark INHERITED;
+};
+
+class SquarePatchBench : public PatchBench {
+public:
+    SquarePatchBench(SkPoint scale, VertexMode vertexMode)
+    : INHERITED(scale, vertexMode) { }
+
+    virtual void appendName(SkString* name) SK_OVERRIDE {
+        name->append("square");
+    }
+    
+    virtual void setCubics() {
+        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
+            //top points
+            {100,100},{150,100},{250,100}, {300,100},
+            //right points
+            {300, 150},{300,250},
+            //bottom points
+            {300,300},{250,300},{150,300},{100,300},
+            //left points
+            {100,250},{100,150}
+        };
+        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
+    }
+private:
+    typedef PatchBench INHERITED;
+};
+
+class LODDiffPatchBench : public PatchBench {
+public:
+    LODDiffPatchBench(SkPoint scale, VertexMode vertexMode)
+    : INHERITED(scale, vertexMode) { }
+    
+    virtual void appendName(SkString* name) SK_OVERRIDE {
+        name->append("LOD_Diff");
+    }
+    
+    virtual void setCubics() {
+        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
+            //top points
+            {100,175},{150,100},{250,100}, {300,0},
+            //right points
+            {300, 150},{300,250},
+            //bottom points
+            {300,400},{250,300},{150,300},{100,225},
+            //left points
+            {100,215},{100,185}
+        };
+        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
+    }
+private:
+    typedef PatchBench INHERITED;
+};
+
+class LoopPatchBench : public PatchBench {
+public:
+    LoopPatchBench(SkPoint scale, VertexMode vertexMode)
+    : INHERITED(scale, vertexMode) { }
+    
+    virtual void appendName(SkString* name) SK_OVERRIDE {
+        name->append("loop");
+    }
+    
+    virtual void setCubics() {
+        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
+            //top points
+            {100,100},{300,200},{100,200}, {300,100},
+            //right points
+            {380, 400},{380,0},
+            //bottom points
+            {300,300},{250,250},{30,200},{100,300},
+            //left points
+            {140,325},{150,150}
+        };
+        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
+    }
+private:
+    typedef PatchBench INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(1.f, 1.0f), PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kBoth_VertexMode); )
+
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.f, 1.0f),
+                                       PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
+                                       PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
+                                       PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
+                                       PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kBoth_VertexMode); )
+
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
+                                       PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.f, 1.0f),
+                                       PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
+                                       PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
+                                       PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
+                                       PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
+                                       PatchBench::kBoth_VertexMode); )
+
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
+                                        PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
+                                        PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
+                                        PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
+                                        PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.f, 1.0f),
+                                        PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
+                                        PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
+                                        PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
+                                        PatchBench::kBoth_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
+                                        PatchBench::kNone_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
+                                        PatchBench::kColors_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
+                                        PatchBench::kTexCoords_VertexMode); )
+DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
+                                        PatchBench::kBoth_VertexMode); )