Initial CL to create Reorder command builder behind a flag

BUG=skia:

Review URL: https://codereview.chromium.org/1129943004
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 9415f30..7ce4ff5 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -173,6 +173,8 @@
       '<(skia_src_path)/gpu/GrRenderTargetPriv.h',
       '<(skia_src_path)/gpu/GrReducedClip.cpp',
       '<(skia_src_path)/gpu/GrReducedClip.h',
+      '<(skia_src_path)/gpu/GrReorderCommandBuilder.h',
+      '<(skia_src_path)/gpu/GrReorderCommandBuilder.cpp',
       '<(skia_src_path)/gpu/GrResourceCache.cpp',
       '<(skia_src_path)/gpu/GrResourceCache.h',
       '<(skia_src_path)/gpu/GrResourceProvider.cpp',
diff --git a/src/gpu/GrCommandBuilder.cpp b/src/gpu/GrCommandBuilder.cpp
index 297424c..2ff59bc 100644
--- a/src/gpu/GrCommandBuilder.cpp
+++ b/src/gpu/GrCommandBuilder.cpp
@@ -7,6 +7,17 @@
 
 #include "GrCommandBuilder.h"
 
+#include "GrInOrderCommandBuilder.h"
+#include "GrReorderCommandBuilder.h"
+
+GrCommandBuilder* GrCommandBuilder::Create(GrGpu* gpu, bool reorder) {
+    if (reorder) {
+        return SkNEW_ARGS(GrReorderCommandBuilder, (gpu));
+    } else {
+        return SkNEW_ARGS(GrInOrderCommandBuilder, (gpu));
+    }
+}
+
 GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect* rect,
                                                      GrColor color,
                                                      bool canIgnoreRect,
diff --git a/src/gpu/GrCommandBuilder.h b/src/gpu/GrCommandBuilder.h
index eb51b5b..90099ee 100644
--- a/src/gpu/GrCommandBuilder.h
+++ b/src/gpu/GrCommandBuilder.h
@@ -17,7 +17,7 @@
     typedef GrTargetCommands::Cmd Cmd;
     typedef GrTargetCommands::State State;
 
-    GrCommandBuilder(GrGpu* gpu) : fCommands(gpu) { }
+    static GrCommandBuilder* Create(GrGpu* gpu, bool reorder);
 
     virtual ~GrCommandBuilder() {}
 
@@ -69,6 +69,8 @@
     typedef GrTargetCommands::CopySurface CopySurface;
     typedef GrTargetCommands::XferBarrier XferBarrier;
 
+    GrCommandBuilder(GrGpu* gpu) : fCommands(gpu) {}
+
     GrTargetCommands::CmdBuffer* cmdBuffer() { return fCommands.cmdBuffer(); }
     GrBatchTarget* batchTarget() { return fCommands.batchTarget(); }
 
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 1b88153..84f7eb2 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -224,6 +224,7 @@
 protected:
     friend class GrCommandBuilder; // for PipelineInfo
     friend class GrInOrderCommandBuilder; // for PipelineInfo
+    friend class GrReorderCommandBuilder; // for PipelineInfo
     friend class GrTargetCommands; // for PipelineInfo
 
     GrContext* getContext() { return fContext; }
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index f28a83f..6b6490c 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -9,7 +9,7 @@
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context)
     : INHERITED(context)
-    , fCommands(SkNEW_ARGS(GrInOrderCommandBuilder, (context->getGpu())))
+    , fCommands(GrCommandBuilder::Create(context->getGpu(), false))
     , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
     , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
     , fPipelineBuffer(kPipelineBufferMinReserve)
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 182ba80..b3de192 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -9,7 +9,7 @@
 #define GrInOrderDrawBuffer_DEFINED
 
 #include "GrDrawTarget.h"
-#include "GrInOrderCommandBuilder.h"
+#include "GrCommandBuilder.h"
 #include "SkChunkAlloc.h"
 
 /**
diff --git a/src/gpu/GrReorderCommandBuilder.cpp b/src/gpu/GrReorderCommandBuilder.cpp
new file mode 100644
index 0000000..3ba95d7
--- /dev/null
+++ b/src/gpu/GrReorderCommandBuilder.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrReorderCommandBuilder.h"
+
+static bool intersect(const SkRect& a, const SkRect& b) {
+    SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom &&
+             b.fLeft <= b.fRight && b.fTop <= b.fBottom);
+    return a.fLeft < b.fRight && b.fLeft < a.fRight &&
+           a.fTop < b.fBottom && b.fTop < a.fBottom;
+}
+
+GrTargetCommands::Cmd* GrReorderCommandBuilder::recordDrawBatch(State* state, GrBatch* batch) {
+    // Check if there is a Batch Draw we can batch with by linearly searching back until we either
+    // 1) check every draw
+    // 2) intersect with something
+    // 3) find a 'blocker'
+    if (!this->cmdBuffer()->empty()) {
+        GrTargetCommands::CmdBuffer::ReverseIter reverseIter(*this->cmdBuffer());
+
+        do {
+            if (Cmd::kDrawBatch_CmdType == reverseIter->type()) {
+                DrawBatch* previous = static_cast<DrawBatch*>(reverseIter.get());
+
+                if (previous->fState->getPipeline()->isEqual(*state->getPipeline()) &&
+                    previous->fBatch->combineIfPossible(batch)) {
+                    return NULL;
+                }
+
+                if (intersect(previous->fBatch->bounds(), batch->bounds())) {
+                    break;
+                }
+            } else {
+                // TODO temporary until we can navigate the other types of commands
+                break;
+            }
+        } while (reverseIter.previous());
+    }
+
+    return GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), DrawBatch, (state, batch,
+                                                                    this->batchTarget()));
+}
diff --git a/src/gpu/GrReorderCommandBuilder.h b/src/gpu/GrReorderCommandBuilder.h
new file mode 100644
index 0000000..99a2c11
--- /dev/null
+++ b/src/gpu/GrReorderCommandBuilder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrReorderCommandBuilder_DEFINED
+#define GrReorderCommandBuilder_DEFINED
+
+#include "GrCommandBuilder.h"
+
+class GrReorderCommandBuilder : public GrCommandBuilder {
+public:
+    typedef GrCommandBuilder::Cmd Cmd;
+    typedef GrCommandBuilder::State State;
+
+    GrReorderCommandBuilder(GrGpu* gpu) : INHERITED(gpu) {}
+
+    Cmd* recordDrawBatch(State*, GrBatch*) override;
+    Cmd* recordStencilPath(const GrPipelineBuilder&,
+                           const GrPathProcessor*,
+                           const GrPath*,
+                           const GrScissorState&,
+                           const GrStencilSettings&) override {
+        SkFAIL("Unsupported\n");
+        return NULL;
+    }
+
+    Cmd* recordDrawPath(State*,
+                        const GrPathProcessor*,
+                        const GrPath*,
+                        const GrStencilSettings&) override {
+        SkFAIL("Unsupported\n");
+        return NULL;
+    }
+
+    Cmd* recordDrawPaths(State*,
+                         GrInOrderDrawBuffer*,
+                         const GrPathProcessor*,
+                         const GrPathRange*,
+                         const void*,
+                         GrDrawTarget::PathIndexType,
+                         const float transformValues[],
+                         GrDrawTarget::PathTransformType ,
+                         int,
+                         const GrStencilSettings&,
+                         const GrDrawTarget::PipelineInfo&) override {
+        SkFAIL("Unsupported\n");
+        return NULL;
+    }
+
+private:
+    typedef GrCommandBuilder INHERITED;
+
+};
+
+#endif
diff --git a/src/gpu/GrTargetCommands.h b/src/gpu/GrTargetCommands.h
index 71ce470..5e35e50 100644
--- a/src/gpu/GrTargetCommands.h
+++ b/src/gpu/GrTargetCommands.h
@@ -65,6 +65,7 @@
 private:
     friend class GrCommandBuilder;
     friend class GrInOrderDrawBuffer; // This goes away when State becomes just a pipeline
+    friend class GrReorderCommandBuilder;
 
     typedef GrGpu::DrawArgs DrawArgs;