Let DM work without a GPU.

Testing:

/m/s/skia (dm) $ d dm; and env GYP_DEFINES=skia_gpu=0 d dm
ninja: Entering directory `out/Debug'
ninja: no work to do.
(294 GMs, 620 benches) x 4 configs, 245 tests
4507 tasks leftUnsupported vertex-color/texture xfer mode.
Unsupported vertex-color/texture xfer mode.
0 tasks left
416.53user 9.86system 0:47.43elapsed 898%CPU (0avgtext+0avgdata
13353376maxresident)k
0inputs+0outputs (0major+3579906minor)pagefaults 0swaps
ninja: Entering directory `out/Debug'
[909/909] LINK dm
(287 GMs, 612 benches) x 4 configs, 227 tests
0 tasks left
365.24user 7.71system 0:14.55elapsed 2562%CPU (0avgtext+0avgdata
14718912maxresident)k
0inputs+0outputs (0major+3328269minor)pagefaults 0swaps

BUG=skia:
R=bsalomon@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/213093004

git-svn-id: http://skia.googlecode.com/svn/trunk@13960 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/dm/DM.cpp b/dm/DM.cpp
index c0715df..a8a2b6d 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -1,8 +1,6 @@
 // Main binary for DM.
 // For a high-level overview, please see dm/README.
 
-#include "GrContext.h"
-#include "GrContextFactory.h"
 #include "SkBenchmark.h"
 #include "SkCommandLineFlags.h"
 #include "SkForceLinking.h"
@@ -14,6 +12,7 @@
 #include "DMBenchTask.h"
 #include "DMCpuGMTask.h"
 #include "DMGpuGMTask.h"
+#include "DMGpuSupport.h"
 #include "DMReporter.h"
 #include "DMTask.h"
 #include "DMTaskRunner.h"
diff --git a/dm/DMBenchTask.cpp b/dm/DMBenchTask.cpp
index 30561a4..c53daf9 100644
--- a/dm/DMBenchTask.cpp
+++ b/dm/DMBenchTask.cpp
@@ -49,7 +49,7 @@
 }
 
 bool GpuBenchTask::shouldSkip() const {
-    return !fBench->isSuitableFor(SkBenchmark::kGPU_Backend);
+    return kGPUDisabled || !fBench->isSuitableFor(SkBenchmark::kGPU_Backend);
 }
 
 static void draw_raster(SkBenchmark* bench, SkColorType colorType) {
@@ -75,8 +75,7 @@
                                          fBench->getSize().y(),
                                          kPMColor_SkColorType,
                                          kPremul_SkAlphaType);
-    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(
-            grFactory->get(fContextType), info, fSampleCount));
+    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
 
     fBench->preDraw();
     fBench->draw(1, surface->getCanvas());
diff --git a/dm/DMGpuGMTask.cpp b/dm/DMGpuGMTask.cpp
index cffa229..c4867b6 100644
--- a/dm/DMGpuGMTask.cpp
+++ b/dm/DMGpuGMTask.cpp
@@ -29,8 +29,7 @@
                                          SkScalarCeilToInt(fGM->height()),
                                          kPMColor_SkColorType,
                                          kPremul_SkAlphaType);
-    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(
-            grFactory->get(fContextType), info, fSampleCount));
+    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
     SkCanvas* canvas = surface->getCanvas();
 
     canvas->concat(fGM->getInitialTransform());
@@ -41,16 +40,12 @@
     bitmap.setConfig(info);
     canvas->readPixels(&bitmap, 0, 0);
 
-#if GR_CACHE_STATS
-    gr->printCacheStats();
-#endif
-
     this->spawnChild(SkNEW_ARGS(ExpectationsTask, (*this, fExpectations, bitmap)));
     this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
 }
 
 bool GpuGMTask::shouldSkip() const {
-    return SkToBool(fGM->getFlags() & skiagm::GM::kSkipGPU_Flag);
+    return kGPUDisabled || SkToBool(fGM->getFlags() & skiagm::GM::kSkipGPU_Flag);
 }
 
 }  // namespace DM
diff --git a/dm/DMGpuGMTask.h b/dm/DMGpuGMTask.h
index 141994e..6e076ec 100644
--- a/dm/DMGpuGMTask.h
+++ b/dm/DMGpuGMTask.h
@@ -2,10 +2,10 @@
 #define DMGpuGMTask_DEFINED
 
 #include "DMExpectations.h"
+#include "DMGpuSupport.h"
 #include "DMReporter.h"
 #include "DMTask.h"
 #include "DMTaskRunner.h"
-#include "GrContextFactory.h"
 #include "SkBitmap.h"
 #include "SkString.h"
 #include "SkTemplates.h"
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
new file mode 100644
index 0000000..46896b4
--- /dev/null
+++ b/dm/DMGpuSupport.h
@@ -0,0 +1,60 @@
+#ifndef DMGpuSupport_DEFINED
+#define DMGpuSupport_DEFINED
+
+// Provides Ganesh to DM,
+// or if it's not available, fakes it enough so most code doesn't have to know that.
+
+#include "SkSurface.h"
+
+#if SK_SUPPORT_GPU
+
+// Ganesh is available.  Yippee!
+
+#  include "GrContext.h"
+#  include "GrContextFactory.h"
+
+namespace DM {
+
+static const bool kGPUDisabled = false;
+
+static inline SkSurface* NewGpuSurface(GrContextFactory* grFactory,
+                                       GrContextFactory::GLContextType type,
+                                       SkImageInfo info,
+                                       int samples) {
+    return SkSurface::NewRenderTarget(grFactory->get(type), info, samples);
+}
+
+}  // namespace DM
+
+#else// !SK_SUPPORT_GPU
+
+// Ganesh is not available.  Fake it.
+
+class GrContextFactory {
+public:
+    typedef int GLContextType;
+
+    static const GLContextType kANGLE_GLContextType  = 0,
+                               kDebug_GLContextType  = 0,
+                               kMESA_GLContextType   = 0,
+                               kNVPR_GLContextType   = 0,
+                               kNative_GLContextType = 0,
+                               kNull_GLContextType   = 0;
+};
+
+namespace DM {
+
+static const bool kGPUDisabled = true;
+
+static inline SkSurface* NewGpuSurface(GrContextFactory*,
+                                       GrContextFactory::GLContextType,
+                                       SkImageInfo,
+                                       int) {
+    return NULL;
+}
+
+}  // namespace DM
+
+#endif//SK_SUPPORT_GPU
+
+#endif//DMGpuSupport_DEFINED
diff --git a/dm/DMTask.h b/dm/DMTask.h
index 4baac44..76efbf9 100644
--- a/dm/DMTask.h
+++ b/dm/DMTask.h
@@ -2,7 +2,7 @@
 #define DMTask_DEFINED
 
 #include "DMReporter.h"
-#include "GrContextFactory.h"
+#include "DMGpuSupport.h"
 #include "SkRunnable.h"
 #include "SkTime.h"
 
diff --git a/dm/DMTaskRunner.h b/dm/DMTaskRunner.h
index c7b4058..b20113f 100644
--- a/dm/DMTaskRunner.h
+++ b/dm/DMTaskRunner.h
@@ -1,7 +1,7 @@
 #ifndef DMTaskRunner_DEFINED
 #define DMTaskRunner_DEFINED
 
-#include "GrContextFactory.h"
+#include "DMGpuSupport.h"
 #include "SkThreadPool.h"
 #include "SkTypes.h"
 
diff --git a/dm/DMTestTask.cpp b/dm/DMTestTask.cpp
index 6c3fced..e16df98 100644
--- a/dm/DMTestTask.cpp
+++ b/dm/DMTestTask.cpp
@@ -50,4 +50,8 @@
     }
 }
 
+bool GpuTestTask::shouldSkip() const {
+    return kGPUDisabled;
+}
+
 }  // namespace DM
diff --git a/dm/DMTestTask.h b/dm/DMTestTask.h
index 87f5920..a65f096 100644
--- a/dm/DMTestTask.h
+++ b/dm/DMTestTask.h
@@ -48,7 +48,7 @@
     GpuTestTask(Reporter*, TaskRunner*, skiatest::TestRegistry::Factory);
 
     virtual void draw(GrContextFactory*) SK_OVERRIDE;
-    virtual bool shouldSkip() const SK_OVERRIDE { return false; }
+    virtual bool shouldSkip() const SK_OVERRIDE;
     virtual SkString name() const SK_OVERRIDE { return fName; }
 
 private:
diff --git a/gyp/most.gyp b/gyp/most.gyp
index 7c32941..3d9bad4 100644
--- a/gyp/most.gyp
+++ b/gyp/most.gyp
@@ -23,15 +23,12 @@
         'pathops_unittest.gyp:*',
         'skpskgr_test.gyp:*',
 #       'pdfviewer.gyp:pdfviewer',
+        'dm.gyp:dm',
       ],
       'conditions': [
         ['skia_os == "android"', {
           'dependencies': [ 'android_system.gyp:SampleApp_APK' ],
         }],
-        # DM assumes you've got a GPU.
-        ['skia_gpu == 1', {
-          'dependencies': [ 'dm.gyp:dm' ],
-        }],
         [ 'skia_skip_gui',
           {
             'dependencies!': [