Make drawIndexedInstances non-virtual and rewrite GrIODB's drawRect on top of drawIndexedInstances.

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/7221078

git-svn-id: http://skia.googlecode.com/svn/trunk@7508 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleManyRects.cpp b/samplecode/SampleManyRects.cpp
new file mode 100644
index 0000000..04d8a41
--- /dev/null
+++ b/samplecode/SampleManyRects.cpp
@@ -0,0 +1,81 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SampleCode.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkPaint.h"
+#include "SkRandom.h"
+#include "SkShader.h"
+#include "SkView.h"
+
+/**
+ * Animated sample used to develop batched rect implementation in GrInOrderDrawBuffer.
+ */
+class ManyRectsView : public SampleView {
+private:
+    enum {
+        N = 1000,
+    };
+
+public:
+    ManyRectsView() {}
+
+protected:
+    virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "ManyRects");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    virtual void onDrawContent(SkCanvas* canvas) {
+        SkISize dsize = canvas->getDeviceSize();
+        SkRect canvasRect = SkRect::MakeWH(SkIntToScalar(dsize.fWidth),
+                                           SkIntToScalar(dsize.fHeight));
+        canvas->clear(0xFFF0E0F0);
+
+        for (int i = 0; i < N; ++i) {
+            SkRect rect = SkRect::MakeWH(SkIntToScalar(fRandom.nextRangeU(10, 100)),
+                                         SkIntToScalar(fRandom.nextRangeU(10, 100)));
+            int x = fRandom.nextRangeU(0, dsize.fWidth);
+            int y = fRandom.nextRangeU(0, dsize.fHeight);
+            canvas->save();
+
+            canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
+            // Rotation messes up the GPU batching because of the clip below. We don't notice
+            // that the rect is inside the clip so the clip changes interrupt batching.
+            if (false) {
+                SkMatrix rotate;
+                rotate.setRotate(fRandom.nextUScalar1() * 360,
+                                 SkIntToScalar(x) + SkScalarHalf(rect.fRight),
+                                 SkIntToScalar(y) + SkScalarHalf(rect.fBottom));
+                canvas->concat(rotate);
+            }
+            SkRect clipRect = rect;
+            // This clip will always contain the entire rect. It's here to give the GPU batching
+            // code a little more challenge.
+            clipRect.outset(10, 10);
+            canvas->clipRect(clipRect);
+            SkPaint paint;
+            paint.setColor(fRandom.nextU());
+            canvas->drawRect(rect, paint);
+            canvas->restore();
+        }
+        this->inval(NULL);
+    }
+
+private:
+    SkMWCRandom fRandom;
+    typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new ManyRectsView; }
+static SkViewRegister reg(MyFactory);