fix dumpcanvas to recurse on pictures and shapes
add cached bitmap for gradients to avoid thrashing textures in gl



git-svn-id: http://skia.googlecode.com/svn/trunk@201 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h
index 5347309..6f16c92 100644
--- a/include/utils/SkDumpCanvas.h
+++ b/include/utils/SkDumpCanvas.h
@@ -49,6 +49,8 @@
     Dumper* getDumper() const { return fDumper; }
     void    setDumper(Dumper*);
     
+    int getNestLevel() const { return fNestLevel; }
+    
     // overrides from SkCanvas
 
     virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
@@ -103,6 +105,7 @@
 
 private:
     Dumper* fDumper;
+    int     fNestLevel; // for nesting recursive elements like pictures
     
     void dump(Verb, const SkPaint*, const char format[], ...);
 
diff --git a/samplecode/SampleTestGL.cpp b/samplecode/SampleTestGL.cpp
new file mode 100644
index 0000000..c12eb7c
--- /dev/null
+++ b/samplecode/SampleTestGL.cpp
@@ -0,0 +1,62 @@
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkCornerPathEffect.h"
+#include "SkCullPoints.h"
+#include "SkGradientShader.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+#include "SkUtils.h"
+
+class TestGLView : public SkView {
+public:
+	TestGLView() {
+    }
+    
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "TestGL");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+    
+    void drawBG(SkCanvas* canvas) {
+        canvas->drawColor(0xFFDDDDDD);
+    }
+    
+    virtual void onDraw(SkCanvas* canvas) {
+        drawBG(canvas);
+        
+        SkRect r;
+        r.set(0, 0, 100, 100);
+        
+        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
+        
+        SkPaint paint;
+        paint.setAntiAlias(false);
+        paint.setColor(SK_ColorRED);
+        
+        canvas->drawRect(r, paint);
+
+        canvas->translate(r.width() + SkIntToScalar(20), 0);
+        paint.setStyle(SkPaint::kStroke_Style);
+        canvas->drawRect(r, paint);
+
+        canvas->translate(r.width() + SkIntToScalar(20), 0);
+        paint.setStrokeWidth(SkIntToScalar(5));
+        canvas->drawRect(r, paint);
+    }
+    
+private:
+    typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new TestGLView; }
+static SkViewRegister reg(MyFactory);
+
diff --git a/samplecode/SampleTriangles.cpp b/samplecode/SampleTriangles.cpp
new file mode 100644
index 0000000..be9da8f
--- /dev/null
+++ b/samplecode/SampleTriangles.cpp
@@ -0,0 +1,118 @@
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkConcaveToTriangles.h"
+
+#define SIZE    SkIntToScalar(150)
+
+typedef void (*PathProc)(SkPath*);
+
+static void make_path0(SkPath* path) {
+    SkRect r;
+    r.set(0, 0, SIZE, SIZE);
+    path->addRect(r);
+}
+
+static void make_path1(SkPath* path) {
+    SkRect r;
+    r.set(0, 0, SIZE, SIZE);
+    path->addRoundRect(r, SIZE/4, SIZE/4);
+}
+
+static void make_path2(SkPath* path) {
+    SkRect r;
+    r.set(0, 0, SIZE, SIZE);
+    path->addOval(r);
+}
+
+static const PathProc gProcs[] = {
+    make_path0,
+    make_path1,
+    make_path2,
+};
+
+#define COUNT_PROCS SK_ARRAY_COUNT(gProcs)
+
+class TriangleView : public SkView {
+public:
+    SkPath fPaths[COUNT_PROCS];
+
+	TriangleView() {
+        for (size_t i = 0; i < COUNT_PROCS; i++) {
+            gProcs[i](&fPaths[i]);
+        }
+    }
+    
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "Triangles");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+    
+    void drawBG(SkCanvas* canvas) {
+        canvas->drawColor(SK_ColorGRAY);
+    }
+    
+    static void draw_path(SkCanvas* canvas, const SkPaint& pathPaint,
+                          const SkPath& path, const SkPaint& triPaint) {
+        canvas->drawPath(path, pathPaint);
+        
+        int n = path.getPoints(NULL, 0);
+        SkPoint* pts = new SkPoint[n];
+        path.getPoints(pts, n);
+        
+        SkTDArray<SkPoint> triangles;
+        if (SkConcaveToTriangles(n, pts, &triangles)) {
+            canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
+                                 triangles.count(), triangles.begin(), NULL,
+                                 NULL, NULL, NULL, 0, triPaint);
+        }
+        
+        SkPaint paint;
+        paint.setColor(SK_ColorGREEN);
+        paint.setStrokeWidth(SkIntToScalar(4));
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts, paint);
+        delete[] pts;
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        this->drawBG(canvas);
+        
+        canvas->translate(SIZE/2, SIZE/2);
+
+        SkPaint pathPaint, triPaint;
+        
+        pathPaint.setColor(SK_ColorBLUE);
+        pathPaint.setStrokeWidth(SIZE / 12);
+
+        triPaint.setColor(SK_ColorRED);
+        triPaint.setStyle(SkPaint::kStroke_Style);
+
+        for (size_t i = 0; i < COUNT_PROCS; i++) {
+            pathPaint.setStyle(SkPaint::kFill_Style);
+            draw_path(canvas, pathPaint, fPaths[i], triPaint);
+
+            canvas->save();
+            canvas->translate(0, SIZE * 6 / 5);
+
+            pathPaint.setStyle(SkPaint::kStroke_Style);
+            draw_path(canvas, pathPaint, fPaths[i], triPaint);
+            
+            canvas->restore();
+            canvas->translate(SIZE * 6 / 5, 0);
+        }
+    }
+    
+private:
+    typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new TriangleView; }
+static SkViewRegister reg(MyFactory);
+
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index 6d7c795..047c482 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -129,6 +129,9 @@
     const uint16_t*     getCache16();
     const SkPMColor*    getCache32();
 
+    // called when we kill our cached colors (to be rebuilt later on demand)
+    virtual void onCacheReset() {}
+
 private:
     enum {
         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
@@ -388,6 +391,8 @@
         fCache16 = NULL;                // inval the cache
         fCache32 = NULL;                // inval the cache
         fCacheAlpha = paintAlpha;       // record the new alpha
+        // inform our subclasses
+        this->onCacheReset();
     }
     return true;
 }
@@ -606,11 +611,24 @@
                     SkShader::TileMode mode, SkUnitMapper* mapper)
         : Gradient_Shader(colors, pos, colorCount, mode, mapper)
     {
+        fCachedBitmap = NULL;
         pts_to_unit_matrix(pts, &fPtsToUnit);
     }
+    virtual ~Linear_Gradient() {
+        if (fCachedBitmap) {
+            SkDELETE(fCachedBitmap);
+        }
+    }
+
     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
     virtual bool asABitmap(SkBitmap*, SkMatrix*, TileMode*);
+    virtual void onCacheReset() {
+        if (fCachedBitmap) {
+            SkDELETE(fCachedBitmap);
+            fCachedBitmap = NULL;
+        }
+    }
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 
         return SkNEW_ARGS(Linear_Gradient, (buffer));
@@ -621,6 +639,8 @@
     virtual Factory getFactory() { return CreateProc; }
 
 private:
+    SkBitmap* fCachedBitmap;    // allocated on demand
+
     typedef Gradient_Shader INHERITED;
 };
 
@@ -731,10 +751,16 @@
 
 bool Linear_Gradient::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
                                 TileMode xy[]) {
+    // we cache our "bitmap", so it's generationID will be const on subsequent
+    // calls to asABitmap
+    if (NULL == fCachedBitmap) {
+        fCachedBitmap = SkNEW(SkBitmap);
+        fCachedBitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
+        fCachedBitmap->setPixels((void*)this->getCache32(), NULL);
+    }
+
     if (bitmap) {
-        bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
-        bitmap->allocPixels();  // share with shader???
-        memcpy(bitmap->getPixels(), this->getCache32(), kCache32Count * 4);
+        *bitmap = *fCachedBitmap;
     }
     if (matrix) {
         matrix->setScale(SkIntToScalar(kCache32Count), SK_Scalar1);
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 7a05f09..2151133 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -1,4 +1,5 @@
 #include "SkDumpCanvas.h"
+#include "SkPicture.h"  
 #include "SkPixelRef.h"
 #include "SkString.h"
 #include <stdarg.h>
@@ -138,7 +139,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkDumpCanvas::SkDumpCanvas(Dumper* dumper) {
+SkDumpCanvas::SkDumpCanvas(Dumper* dumper) : fNestLevel(0) {
     dumper->safeRef();
     fDumper = dumper;
 
@@ -352,10 +353,20 @@
 
 void SkDumpCanvas::drawShape(SkShape* shape) {
     this->dump(kDrawShape_Verb, NULL, "drawShape(%p)", shape);
+    fNestLevel += 1;
+    this->INHERITED::drawShape(shape);
+    fNestLevel -= 1;
+    this->dump(kDrawShape_Verb, NULL, "endShape(%p)", shape);
 }
 
 void SkDumpCanvas::drawPicture(SkPicture& picture) {
-    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p)", &picture);
+    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %d:%d", &picture,
+               picture.width(), picture.height());
+    fNestLevel += 1;
+    this->INHERITED::drawPicture(picture);
+    fNestLevel -= 1;
+    this->dump(kDrawPicture_Verb, NULL, "endPicture(%p) %d:%d", &picture,
+               picture.width(), picture.height());
 }
 
 void SkDumpCanvas::drawVertices(VertexMode vmode, int vertexCount,
@@ -397,7 +408,7 @@
 void SkFormatDumper::dump(SkDumpCanvas* canvas, SkDumpCanvas::Verb verb,
                           const char str[], const SkPaint* p) {
     SkString msg, tab;
-    const int level = canvas->getSaveCount() - 1;
+    const int level = canvas->getNestLevel() + canvas->getSaveCount() - 1;
     SkASSERT(level >= 0);
     for (int i = 0; i < level; i++) {
         tab.append("\t");
diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
index c55cbc8..fb0cd3b 100644
--- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
+++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj
@@ -72,6 +72,8 @@
 		00A41E4B0EFC312F00C9CBEB /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; };
 		00A728270FD43D0400D5051F /* SampleMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6760FCCCB01002BD8B4 /* SampleMovie.cpp */; };
 		00A7282F0FD43D3700D5051F /* SkMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A7282D0FD43D3700D5051F /* SkMovie.cpp */; };
+		00A7295D0FD8397600D5051F /* SampleAll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6740FCCCB01002BD8B4 /* SampleAll.cpp */; };
+		00A729650FD93ED600D5051F /* SampleTestGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A729630FD93ED600D5051F /* SampleTestGL.cpp */; };
 		00C55DA10F8552DC000CAC09 /* SampleGradients.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00C55DA00F8552DC000CAC09 /* SampleGradients.cpp */; };
 		00FF39140FC6ED2C00915187 /* SampleEffects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00FF39130FC6ED2C00915187 /* SampleEffects.cpp */; };
 		0156F80407C56A3000C6122B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0156F80307C56A3000C6122B /* Foundation.framework */; };
@@ -79,7 +81,6 @@
 		2762F66D0FCCCABE002BD8B4 /* SkFlipPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F66B0FCCCABE002BD8B4 /* SkFlipPixelRef.cpp */; };
 		2762F66E0FCCCABE002BD8B4 /* SkPageFlipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F66C0FCCCABE002BD8B4 /* SkPageFlipper.cpp */; };
 		2762F67D0FCCCB01002BD8B4 /* SamplePageFlip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6770FCCCB01002BD8B4 /* SamplePageFlip.cpp */; };
-		2762F6800FCCCB07002BD8B4 /* SampleAll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6740FCCCB01002BD8B4 /* SampleAll.cpp */; };
 		8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
 		8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; };
 		8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
@@ -198,6 +199,7 @@
 		00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleArc.cpp; path = ../../samplecode/SampleArc.cpp; sourceTree = SOURCE_ROOT; };
 		00A7282D0FD43D3700D5051F /* SkMovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie.cpp; path = ../../src/images/SkMovie.cpp; sourceTree = SOURCE_ROOT; };
 		00A7282E0FD43D3700D5051F /* SkMovie_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie_gif.cpp; path = ../../src/images/SkMovie_gif.cpp; sourceTree = SOURCE_ROOT; };
+		00A729630FD93ED600D5051F /* SampleTestGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleTestGL.cpp; path = ../../samplecode/SampleTestGL.cpp; sourceTree = SOURCE_ROOT; };
 		00C55DA00F8552DC000CAC09 /* SampleGradients.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleGradients.cpp; path = ../../samplecode/SampleGradients.cpp; sourceTree = SOURCE_ROOT; };
 		00D6B5CB0F72DC4300C466B9 /* SampleFuzz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFuzz.cpp; path = ../../samplecode/SampleFuzz.cpp; sourceTree = SOURCE_ROOT; };
 		00FF39130FC6ED2C00915187 /* SampleEffects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleEffects.cpp; path = ../../samplecode/SampleEffects.cpp; sourceTree = SOURCE_ROOT; };
@@ -240,6 +242,7 @@
 		00003C610EFC2287000FF73A /* samples */ = {
 			isa = PBXGroup;
 			children = (
+				00A729630FD93ED600D5051F /* SampleTestGL.cpp */,
 				2762F6740FCCCB01002BD8B4 /* SampleAll.cpp */,
 				2762F6760FCCCB01002BD8B4 /* SampleMovie.cpp */,
 				2762F6770FCCCB01002BD8B4 /* SamplePageFlip.cpp */,
@@ -572,9 +575,10 @@
 				2762F66D0FCCCABE002BD8B4 /* SkFlipPixelRef.cpp in Sources */,
 				2762F66E0FCCCABE002BD8B4 /* SkPageFlipper.cpp in Sources */,
 				2762F67D0FCCCB01002BD8B4 /* SamplePageFlip.cpp in Sources */,
-				2762F6800FCCCB07002BD8B4 /* SampleAll.cpp in Sources */,
 				00A728270FD43D0400D5051F /* SampleMovie.cpp in Sources */,
 				00A7282F0FD43D3700D5051F /* SkMovie.cpp in Sources */,
+				00A7295D0FD8397600D5051F /* SampleAll.cpp in Sources */,
+				00A729650FD93ED600D5051F /* SampleTestGL.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/xcode/sampleapp_sdl/SDLApp.xcodeproj/project.pbxproj b/xcode/sampleapp_sdl/SDLApp.xcodeproj/project.pbxproj
index b348e94..e7f6692 100644
--- a/xcode/sampleapp_sdl/SDLApp.xcodeproj/project.pbxproj
+++ b/xcode/sampleapp_sdl/SDLApp.xcodeproj/project.pbxproj
@@ -73,6 +73,8 @@
 		006DC7EC0FC7475F00BF5F45 /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 006DC7E90FC7475900BF5F45 /* libcore.a */; };
 		00A728490FD43E7600D5051F /* SampleMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0064EE0C0FC72BEE00D71FB0 /* SampleMovie.cpp */; };
 		00A7284D0FD43E8900D5051F /* SkMovie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A7284B0FD43E8900D5051F /* SkMovie.cpp */; };
+		00A728C80FD6C03000D5051F /* SampleTriangles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A728C70FD6C03000D5051F /* SampleTriangles.cpp */; };
+		00A728DD0FD6EDA700D5051F /* SkConcaveToTriangles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A728DC0FD6EDA700D5051F /* SkConcaveToTriangles.cpp */; };
 		2762F6040FCCC832002BD8B4 /* SampleShapes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0064EE190FC72BEE00D71FB0 /* SampleShapes.cpp */; };
 		2762F6420FCCCA6C002BD8B4 /* SkFlipPixelRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6400FCCCA6C002BD8B4 /* SkFlipPixelRef.cpp */; };
 		2762F6430FCCCA6C002BD8B4 /* SkPageFlipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F6410FCCCA6C002BD8B4 /* SkPageFlipper.cpp */; };
@@ -213,6 +215,8 @@
 		0096585B0FC7201800C3AE15 /* maccore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = maccore.xcodeproj; path = ../maccore/maccore.xcodeproj; sourceTree = SOURCE_ROOT; };
 		00A7284B0FD43E8900D5051F /* SkMovie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie.cpp; path = ../../src/images/SkMovie.cpp; sourceTree = SOURCE_ROOT; };
 		00A7284C0FD43E8900D5051F /* SkMovie_gif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkMovie_gif.cpp; path = ../../src/images/SkMovie_gif.cpp; sourceTree = SOURCE_ROOT; };
+		00A728C70FD6C03000D5051F /* SampleTriangles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleTriangles.cpp; sourceTree = "<group>"; };
+		00A728DC0FD6EDA700D5051F /* SkConcaveToTriangles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkConcaveToTriangles.cpp; path = ../../src/core/SkConcaveToTriangles.cpp; sourceTree = SOURCE_ROOT; };
 		089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 		1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
 		2762F6400FCCCA6C002BD8B4 /* SkFlipPixelRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFlipPixelRef.cpp; path = ../../src/images/SkFlipPixelRef.cpp; sourceTree = SOURCE_ROOT; };
@@ -254,6 +258,7 @@
 				0064EDF10FC72BEE00D71FB0 /* SampleApp.cpp */,
 				0064EDF20FC72BEE00D71FB0 /* SampleArc.cpp */,
 				0064EDF30FC72BEE00D71FB0 /* SampleBitmapRect.cpp */,
+				00A728C70FD6C03000D5051F /* SampleTriangles.cpp */,
 				0064EDF40FC72BEE00D71FB0 /* SampleCamera.cpp */,
 				0064EDF50FC72BEE00D71FB0 /* SampleCircle.cpp */,
 				0064EDF60FC72BEE00D71FB0 /* SampleCode.h */,
@@ -403,6 +408,7 @@
 		277836430FCF890D006549E4 /* opengl */ = {
 			isa = PBXGroup;
 			children = (
+				00A728DC0FD6EDA700D5051F /* SkConcaveToTriangles.cpp */,
 				277836370FCF8908006549E4 /* SkGL.cpp */,
 				277836380FCF8908006549E4 /* SkGLCanvas.cpp */,
 				277836390FCF8908006549E4 /* SkGLDevice.cpp */,
@@ -632,6 +638,8 @@
 				2779F2540FD614D1005D376E /* SampleAll.cpp in Sources */,
 				2779F2610FD61678005D376E /* SampleXfermodes.cpp in Sources */,
 				2779F27E0FD61829005D376E /* SampleText.cpp in Sources */,
+				00A728C80FD6C03000D5051F /* SampleTriangles.cpp in Sources */,
+				00A728DD0FD6EDA700D5051F /* SkConcaveToTriangles.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};